Наиболее часто ошибки возникают при работе с файлами на внешних устройствах. Может произойти сбой записи на дискету, нерадивый пользователь норовит забыть вставить дискету в дисковод, другой любит класть диски в CD ROM не той стороной и т.д. В результате, если не принять особых мер, будут происходить фатальные ошибки и вся программа позорно "свалится" из-за такой мелочи, как ошибка записи или считывания файла.
Существует несколько способов решения указанной проблемы. Во-первых, надо сообщить транслятору, что в данном месте программы надо реагировать на ошибки ввода-вывода спокойнее, а точнее говоря, вовсе их не замечать. Указания транслятору даются при помощи так называемых директив.
Директива – особый объект в тексте программы, управляющий режимами компиляции программы. На Паскале директивы записываются в фигурных скобках, причем сразу после открывающей скобки идет знак доллара, а за ним – имя директивы и, если необходимо, дополнительные параметры.
За ввод-вывод отвечает директива I.
{$I-} – отключить контроль ввода-вывода; {$I+} – включить контроль ввода-вывода.
Таким образом, чтобы обезопасить процедуру записи информации в файл, следует написать:
{$I-}
Writeln(f,s);
{$I+}
Теперь программа не будет реагировать на сбой при записи. Но как же узнать, не случилось что-то страшное, раз контроль отключен? Для этого есть функция IORESULT, которая возвращает код результата выполнения последней операции ввода-вывода. Если это 0 – все нормально, иначе – ошибка. После вызова функции ее значение сбрасывается, поэтому обычно его сохраняют в переменную. Проверка выглядит следующим образом:
{$I-}
Writeln(f,s); IF IOResult<>0 THEN WriteLn(’Ошибка записи’)
{$I+}
В языке Delphi предусмотрено очень мощное и удобное средство обработки ошибок – оператор TRY:
TRY
опасное место в программе
EXCEPT
выполняется при возникновении ошибки
END;
Если на участке между TRY и EXCEPT возникнет ошибка, то будут выполняться операторы, стоящие между EXCEPT и END, иначе они пропускаются, и выполняется команда, следующая за END. В реальной программе оператор TRY выглядит примерно так:
TRY reset(f); WriteLn(f,’123’); Close(f) EXCEPT MessageBox(‘Ошибка записи в файл’); END;
По мнению известного специалиста в области программирования Э. Дейкстры "…если отладка – процесс устранения ошибок в программах, то программирование – процесс их внесения". Увы, написать сложную программу без ошибок практически невозможно. Процесс "доведения до ума" программы называется отладкой (debugging).
Интересно происхождение английского термина debug, буквально означающего "обезжучивание" (англ. bug означает "жук"). В 40-х гг. ХХ века во флоте США эксплуатировался компьютер Mark-1. Однажды машина вышла из строя по причине попадания самого настоящего жука в контакты одного из многих тысяч реле. Математик Г.М. Хоппер, разрабатывавшая программы для Mark-1, записала в журнале "Реле №70. Произведено обезжучивание". С тех пор термин debug прижился для обозначения процесса отладки.
Еще сравнительно недавно отладка программы была весьма трудоемким и утомительным делом. Работа с компиляторами таких языков, как C, Fortran или Clipper в ОС MS DOS выглядела следующим образом. Текст программы набирался в любом текстовом редакторе – от Word до блокнота. Далее запускался компилятор, которому на вход подавался файл с программой. Если компиляция проходила успешно, компилятор создавал так называемый объектный файл. Затем запускался линкер – программа, объединяющая код стандартных библиотек и код в объектном файле в окончательный exe-файл. Наконец, полученный exe-файл запускался на выполнение. Если в нем обнаруживалась ошибка, весь процесс надо было повторять заново.