Песни о Паскале — страница 31 из 112

Полюбуйтесь, во что превратила эта программа один из файлов на Паскале (приведен небольшой фрагмент).


}"Rtqi2420rcu"

xct"Ocp"<"uvtkpi=

}///"░гьёднзпкз"▒т░шзжхтэ"///

rtqegfwtg"Rcwug=

dgikp

"""""Ytkvgnp*)Пвиокфз"Gpvgt<)+=""Tgcfnp=


Как говорится, родная мама не узнает! Все, что попадает в «мясорубку» нашего шифровальщика, обращается в фарш. Однако последующая расшифровка «перемолотого» файла в точности восстановила его.

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

Итоги

• Для записи в текстовый файл, как и для чтения, требуется файловая переменная типа TEXT.

• Перед записью выполняют два действия: связывание переменной с файлом процедурой Assign и открытие файла для записи процедурой Rewrite.

• Вызов процедуры Rewrite либо создаёт новый файл, либо очищает существующий (вся бывшая в нём информация теряется!).

• Запись отдельных строк в файл выполняют процедурой Writeln, первым параметром здесь указывают файловую переменную.

• По окончании записи файл закрывают процедурой Close, – это гарантирует сохранение данных на диске.

А слабо?

А) Программа создает файл, печатает в него несколько строк с числами, а затем выводит этот файл на экран. Воспользуйтесь одной файловой переменной.

Б) Программа для нумерации строк файла. Строки исходного файла должны копироваться в конечный файл с добавлением перед каждой строкой её номера, например:

Исходный файл:


В лесу родилась елочка,

В лесу она росла.

Зимой и летом стройная,

Зеленая была.


Конечный файл:


1

В лесу родилась елочка,

2

В лесу она росла.

3

Зимой и летом стройная,

4

Зеленая была.


В) Скопировать один файл в другой:

• с перестановкой местами четных и нечетных строк;

• с перестановкой строк в обратном порядке (см. условие задачи «Е» к 25-й главе).

Г) Для передачи по интернету секретного текстового файла разбейте его на два других: в первый запишите нечетные строки исходного файла, а во второй – четные. Напишите для этого программу, или слабо?

Д) Создайте программу для объединения двух файлов (см. условие предыдущей задачи). Из первого составьте нечетные строки конечного файла, а из второго – четные.

Глава 27Дайте кораблю минутный отдых!



Ой, что мы с вами натворили! Могучая программа шифрования файлов дает нам право если не на медаль, то хотя бы на передышку. Пощадим наши серые клеточки и отправимся на экскурсию по своему кораблю – среде программирования Free Pascal. Ведь мы обошли ещё не все палубы этого лайнера. Сейчас рассмотрим настройку компилятора, а в следующей главе обсудим возможности текстового редактора и справочной системы.

Ошибка ошибке рознь

Где найти безгрешных программистов? Нет таковых! Лихорадочно барабаня по клавишам в попытке изваять очередной проект, мы то и дело ошибаемся. Часть этих ошибок отлавливает компилятор, – он видит синтаксические ошибки – нарушения правил языка. Вы споткнулись на ключевом слове или забыли объявить переменную? – нажмите клавишу F9, и компилятор «ткнет носом» в место ошибки. И пока не исправите свои огрехи, не надейтесь получить исполняемый файл. Зато и работают такие программы, «непосильным трудом нажитые», весьма надежно. Восхищенный новичок однажды породил афоризм: «компилируется – значит работает». Увы! если бы так! Некоторые ошибки проявляются лишь во время работы программы, – это ошибки времени исполнения – Runtime errors.

Фатальные ошибки

Да, компилятор Паскаля способен уберечь от многих ошибок, но посмотрите на следующий пример.


var X : integer;

begin

      Readln(X);

      Writeln(100 div X);

end.


Программа печатает результат деления числа 100 на переменную X. Здесь нет синтаксических ошибок. И все работает прекрасно, пока пользователь не введет число ноль. Тогда вместо результата деления вы получите неприятное сообщение «Runtime error 200», и программа прервется. Иначе говоря, деление на ноль не позволено никому, даже компьютеру.

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


var X : integer;

begin

      Readln(X);

      if X<>0

      then Writeln(100 div X)

      else Writeln(’Не делите на ноль, умоляю Вас!’);

end.


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

«Простительные» ошибки

Вот пример по части обработки файлов, – на этой «кухне» мы уже побывали. Попытка открыть для чтения несуществующий файл влечет ошибку вода/вывода (по-английски – «I/O Error»), – это тоже ошибка времени исполнения. Кто виноват? Разумеется, пользователь, – данные надо вводить внимательней. Но программе от этого не легче, – она обязана как-то реагировать. Как? Проще всего аварийно завершиться. Но можно поступить мягче – разобраться в ситуации и подсказать пользователю, где он неправ.

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

Опции компилятора

Обратимся к настройкам компилятора. Щелкните по пункту меню Options –> Compiler… (рис. 60), и перед вами появится окно для настройки опций (рис. 61).



Рис.60 – Выбор пункта меню для настройки опций компилятора


Рис.61 – Окно настроек опций компилятора

Вкладка «Generation code» содержит нужную нам группу флажков «Code generation». Флажок «I/O checking» заведует реакцией программы на ошибки ввода-вывода («I/O» – это сокращение от Input/Output – «ввод/вывод»). При установленном флажке компилятор будет создавать исполняемые EXE–файлы так, что ошибки ввода-вывода аварийно завершат программу. А если сбросить флажок и снова откомпилировать ту же программу, она поведет себя иначе, – программа не погибнет, однако и работать, как следует, не будет. В чем же смысл настройки?

Обработка ошибок ввода-вывода

Смысл в том, чтобы самому следить за вероятными ошибками. Для слежки используют функцию IOResult, которая не имеет параметров и возвращает ноль, если ошибок ввода-вывода не произошло. А если эта неприятность все же случилась, функция вернет ненулевой код ошибки, по которому легко выяснить её причину. Обратите внимание: функция возвращает состояние последней выполнявшейся операции ввода-вывода. При ошибке дальнейшая работа с файлом автоматически блокируется до его повторного открытия.

Рассмотрим способ безаварийного определения наличия файла на диске (здесь имя файла содержится в переменной FileName).


Assign(F, FileName); Reset(F);

if IOResult=0

      then Writeln (’Нашелся файл ’+ FileName)

      else Writeln (’Файл ’+FileName+’ не обнаружен!’);


Этот фрагмент надёжно сработает только при отключенном флажке «I/O checking», иначе программа может прерваться аварийно. Стало быть, перед компиляцией надо проверять состояние флажка, а это хлопотно и ненадежно.

В настройках опций компилятора через меню есть и другой изъян. Как быть, когда в разных местах программы требуется по-разному реагировать на ошибки: где-то включить этот контроль, а где-то нет? Но флажок действует на всю программу в целом, глобально, – он не допускает выборочной настройки. Что делать?