Спасение утопающих...

Создание надежной программы сродни созданию нового самолета. Процесс отладки программы может продолжаться бесконечно долго, но устранить все ошибки все равно невозможно. Их наличие в программе не так страшно, как в случае с самолетом, пользователь не погибнет, но сколько нервных клеток они ему сожгут.

По известным всем законам программа в присутствии автора работает как часы. Стоит ему отойти, как она начинает показывать свой дикий нрав и ошибки сыпятся как из рога изобилия. Виноват в этом программист. Не учел он, что в человеческой природе заложена страсть к саморазрушению.

Рассмотрим следующую ситуацию. Вы целый день набирали текст в редакторе. Рабочий день закончился и вы решили сохранить результаты своего титанического труда на дискете. По всем правилам Вы задали название файла и нажали клавишу <Enter>. Начинается самое интересное. Вы забыли вставить дискету в дисковод. В результате - программа зависла, результаты работы потеряны и вы медленно впадаете в транс, поминая при этом недобрым словом программистов и их родственников.

Надеюсь, такая неприятность обошла вас стороной. Но если вы программист, она научила вас заботиться о пользователях ваших программных продуктов. Конечно, в этой ситуации виноват пользователь. Но хороший программист должен был это предвидеть. Программа - его детище, его любимая женщина. Она требует постоянного внимания к себе и не позволяет ни на минуту расслабиться. Расслабился, отвлекся - ситуация вышла из-под контроля. Все начинай сначала.

Программист должен помнить, что программы нужно писать на "дурака", предусматривая при этом защиту от "дурака".

Первое подразумевает написание программ, для работы с которыми пользователю достаточно быть специалистом в своей области и не нужны глубокие знания в области компьютеров. О создании таких программ нельзя рассказать одним абзацем. Вернемся к нему позже.

Давайте лучше поговорим о защите от "дурака". Именно она оговаривает, что должен сделать программист для того, чтобы не возникало описанных выше ситуаций. Компиляторы языков программирования выполняют защиту автоматически, но делают это очень своеобразно. В случае возникновения критической ситуации выполнение программы немедленно прекращается и на экран монитора выдается номер ошибки и, иногда, комментарий о ее причине.

Дальнейшее повествование я буду вести, опираясь на возможности, предоставляемые языком Basic для DOS фирмы Microsoft. Среди крутых программистов бытует мнение, что Basic - это несерьезно. Вполне возможно. Для написания операционной систем и утилит для нее Basic мало пригоден. Компилятор имеет ограничения. Но за пять лет его использования в моей предметной области не нашлось задач, которые я не смог бы решить с его помощью.

Любая программа, написанная на языке Basic, имеет строку с номером 0 (ноль). Вы не найдете ее, просматривая исходные тексты программ. Она присоединяется к программе при выполнении в среде или при создании exe-файла. В этой строке записан код подпрограммы, выполняющей обработку критических ошибок, возникающих при выполнении программы. Именно эта подпрограмма выводит на экран сообщение об ошибке, прерывает выполнение программы и сохраняется код ошибки в переменной ERR.

Basic предоставляет программисту возможность создать собственную подпрограмму обработки критических ошибок. Коды ошибок и их описание можно найти в документации, Help'е или в книгах по языку Basic. Как написать собственную подпрограмму обработки критических ошибок, разберем на примере ошибки: "Нет дискеты в дисководе". Пример программы представлен на рисунке.

Если вы попытались выполнить операцию чтения/записи файла, но в дисководе нет дискеты, то произойдет критическая ситуация. В переменной ERR будет сохранен код ошибки (ERR=71). После этого нормальная работа программы будет прервана и управление получит подпрограмма обработки критических ошибок.

Для того, чтобы выделить из общей массы нашу ошибку, используем оператор Select Case с переменной ERR в качестве условия поиска.

Если значение переменной ERR=71, то будет подан звуковой сигнал и на экран выведено сообщение, подсказывающее пользователю, что он забыл вставить дискету в дисковод. Кроме того, пользователю предоставлена возможность решить, как дальше будет работать программа. Для этого, с помощью функции Inkey$, в теле бесконечного цикла операторов Do ... Loop, из буфера клавиатуры считываются скан-коды нажатых клавиш.

Если пользователь нажмет на клавиатуре клавишу <Esc> - завершит работу программа, если клавишу <Enter> - завершит работу подпрограмма обработки критических ошибок и выполнение основной программы продолжится с оператора явившегося виновником возникновения ошибки. В нашей программе это оператор Open.

Как вы помните, по умолчанию обработка критических ошибок выполняется подпрограммой, расположенной в строке 0. Для того, чтобы использовать нашу подпрограмму, а не стандартную, в текст основной программы перед оператором Open запишем оператор On Error GoTo NoDisk. Теперь всякий раз, когда будет возникать критическая ошибка, ее обработка будет выполняться подпрограммой NoDisk.

Подпрограмма NoDisk не является универсальной. В ней мы обрабатываем одну ошибку из многих. Возникновение любой другой приведет к появлению на экране сообщения: "Неизвестная ошибка", ее кода и немедленному завершению работы программы. В то же время, стандартная подпрограмма для некоторых ошибок погрозит пальчиком, но продолжит работу. Поэтому, после завершения выполнения критичного к возникновению 71 ошибки участка программы лучше вернуться к стандартной подпрограмме. Для этого в тексте программы после оператора Open вставим строку On Error GoTo 0.

Как видите, провести обработку ошибок по собственному сценарию очень просто. Нужно только четко понимать, в каком месте программы и по какой причине ошибки могут возникнуть. А причин, поверьте моему опыту, более чем достаточно - ведь каждое устройство, файл, с которым вы работаете являются потенциальными источниками ошибок.

Дочитав до этого места, Вы получили достаточный запас знаний, чтобы приступить к его немедленному использованию. Напишите программу, которая не будет распечатывать результаты на принтере, если принтер не готов или в принтере нет бумаги. Предоставьте пользователю возможность решить, что делать дальше. Печатать или не печатать?

Сергей ОСОКО

‘Основная программа
‘Определение подпрограммы обработки ошибки: Нет дискеты
ON ERROR GOTO NoDisk
‘Попытка открытия файла vc.com на диске a:
OPEN "a:\vc.com" FOR INPUT AS 1
"Определение стандартной программы обработки ошибок
ON ERROR GOTO 0
PRINT "Дискета в дисководе"
END
NoDisk:
"Подпрограмма обработки ошибки: Нет дискеты
 SELECT CASE ERR
 CASE 71	
 BEEP ‘Подать звуковой сигнал
 PRINT "Внимание"
 PRINT "Нет дискеты.Вставьте дискету и нажмите:"
 PRINT " <Enter> - чтобы повторить или"
 PRINT " <Esc> - чтобы завершить работу программы"
 DO
 PressKey$ = INKEY$
 SELECT CASE PressKey$
 CASE CHR$(13) 'Нажата клавиша <Enter>
 RESUME ‘выполнить оператор Open
 CASE CHR$(27) 'Нажата клавиша <Esc>
 END ‘завершить программу
 END SELECT
 LOOP
 CASE ELSE
 PRINT "Неизвестная ошибка:"; ERR
 END
 END SELECT
Версия для печатиВерсия для печати

Номер: 

35 за 1997 год

Рубрика: 

Азбука программирования
Заметили ошибку? Выделите ее мышкой и нажмите Ctrl+Enter!