double arrow

Оператор ON ERROR GOTO

Обработка ошибок

Рассмотрим следующий пример:


'Программа, при выполнении которой возможна ошибка
DIM a!
INPUT "Введите, пожалуйста, число ",а!
PRINT 5000 / а!
'Конец программы

Эта программа работает до тех пор, пока в качестве входной информации не будет введен нуль. При вводе "нуля" диагностируется ошибка (Run-time error), так как операция деления на нуль недопустима. Такая ситуация должна быть предупреждена программистом введением контроля над вводимым числом.


'Ошибка нейтрализована
DIM a!
DO
INPUT "Введите, пожалуйста, число ",а1
UNTIL a!<>0
PRINT 5000 / а!
'Конец программы

Однако имеется целый ряд ситуаций, приводящих к ошибкам, которые нельзя устранить, используя контроль вводимых данных. Рассмотрим следующий пример:


'Программа с возможной ошибкой принтера
LPRINT "Druckausgabe 1"
LPRINT "Druckausgabe 2"
LPRINT "Druckausgabe 3"
'Конец программы

Вызовите программу, не включив принтер. Вы получите сообщение об ошибке (Run- time error). To же самое произойдет, если Вы выключите принтер (или установите его в режим "OFFLINE") в то время, когда программа пытается передавать ему данные. Рассмотрим методы, которые позволяют программе реагировать на такие ошибки.

Определяет подпрограмму обработки ошибок и имеет формат:
ON ERROR GOTO Метка

Если в процессе выполнения программы произошла ошибка, то оператор ON ERROR GOTO передаст управление на определенную метку. При этом стандартный метод обработки ошибок выполнения QBASIC блокируется. Подпрограмма обработки ошибок всегда должна завершаться оператором RESUME NEXT. Точное значение этого оператора будет объяснено ниже.

'Программа с ошибкой деления
ON ERROR GOTO FehlerHandler
PRINT "Вывод проведенных вычислений"
'строка-провокатор
PRINT 1000/0
END 'здесь основная программа кончается
'Конец программы
'начало собственной программы обработки ошибок
FehlerHandler:
PRINT "Найдена ошибка"
PRINT RESUME NEXT

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

· ERDEV Последний код ошибки устройства

· ERDEV$ Соответствующее имя устройства

· ERR Код ошибки выполнения

Значение этих переменных можно анализировать в собственной программе обработки ошибок:

'Программа с ошибкой деления
ON ERROR GOTO FehlerHandler
PRINT "Вывод проведенных вычислений"
'строка с возможной ошибкой
PRINT 1000/0
END 'здесь кончается основная программа
'Конец программы
'начало собственной программы обработки ошибок
FehlerHandler
PRINT
PRINT" ———————————————"
PRINT "Найдена ошибка
PRINT "код ошибки устройства:"; ERDEV
PRINT "устройство ", ERDEV$
PRINT "Код ошибки выполнения:"; ERR
PRINT "———————————————"
PRINT RESUME NEXT

В справочно-информационной системе (Help) QBASICa имеется список всех возможных ошибок выполнения (Run-time error). В приведенной ниже таблице собраны наиболее часто встречающиеся сообщения об ошибках и их коды:

Код Ошибка
  Деление на нуль
  Прерывание устройств по времени (Time out)
  Общая ошибка устройства
  Конец бумаги
  Недопустимое имя или номер файла
  Файл не найден
  Ошибочный режим файла
  Файл уже открыт
  Ошибка устройства ввода/вывода
  Файл уже существует
  Переполнение диска
  Недопустимое имя файла
  Устройство недоступно
  Доступ запрещен
  Диск не готов
  Ошибка носителя
  Ошибка доступа
  Путь не найден

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

· RESUME

· RESUME Метка_перехода

· RESUME NEXT

RESUME NEXT продолжает программу со строки, следующей за предложением, в котором обнаружена ошибка. С помощью оператора RESUME Метка_перехода можно перейти в любую точку программы, a RESUME без дополнений вызывает повторное выполнение ошибочного фрагмента. Для оценки кода ошибки выполнения лучше всего использовать оператор SELECT...CASE.

'обработка ошибок
ON ERROR GOTO FehlerHandler
PRINT "Вывод вычислений"
PRINT 1000 / О"
LPRINT "Вывод на печать"
OPEN "GIBTESNI.CHT" FOR INPUT AS #1
END 'здесь основная программа кончается'
'начало собственной программы обработки ошибок
FehlerHandler:
PRINT"—————————————"
PRINT "Найдена ошибка "
SELECT CASE ERR
CASE ERR=11 'деление на ноль
PRINT "при программировании можно усложнить
RESUME NEXT CASE ERR=27 'конец бумаги
PRINT "Вставьте бумагу"
PRINT "Нажмите любую клавишу"
DO WHILE INKKEY$=""
LOOP
RESUME CASEERR=25 AND MID$(ERDEV$,1,3)-"LPT"
'ошибка принтера
PRINT "Подготовьте принтер"
PRINT "Нажмите любую клавишу"
DO WHILE INKEY$=""
LOOP
RESUME CASE ELSE
CLS
PRINT "Код ошибки:"; err
PRINT "Придется прервать программу"
END SELECT

Приведенная подпрограмма реагирует на ошибку, вызванную делением на нуль, обходом ошибочной строки (RESUME NEXT). При этом выдается сообщение об ошибке. Если обнаружена ошибка принтера, выдается рекомендация по ее устранению. Если прозойдет ошибка, код которой не анализируется ветвями CASE ERR, то становится активной ветвь CASE ELSE, программа выводит код ошибки и прерывает работу. В предложенном примере это произойдет при попытке открыть несуществующий файл "GIBTESNI.CHT".


Понравилась статья? Добавь ее в закладку (CTRL+D) и не забудь поделиться с друзьями:  



Сейчас читают про: