учебник по паскалю. Программа 5 Алгоритм 5 Свойства алгоритма 6 Формы записи алгоритма 6
Скачать 2.21 Mb.
|
21. Текстовые файлыДля написания большинства сложных программ требуется обмен данными с файлами. В этой главе мы рассмотрим только текстовые файлы, для работы с бинарными и типизированными файлами см. специальную литературу и гл. 22. 21.1. Общие операцииДля работы с каждым файлом описывается переменная типа text: var f:text; Ее называют файловой переменной. Если программа обрабатывает несколько файлов одновременно, для каждого из них описывается такая переменная. Можно использовать и одну переменную для нескольких файлов, если они обрабатываются последовательно, и каждый следующий файл открывается после завершения работы с предыдущим. Вся работа с файлом происходит через файловую переменную, имя файла указывается только один раз следующим оператором: assign (f,'имя_файла'); где f -- ранее описанная файловая переменная. Этот оператор предшествует открытию файла и связывает переменную с файлом на жестком или гибком диске. В качестве имени файла может быть указан абсолютный или относительный путь к файлу на жестком или сменном диске: assign (f,'data.txt'); -- будет открываться файл с именем data.txt из текущей папки; assign (f,'a:\my.dat'); -- будет открыт файл с именем my.dat из корневой папки дискеты. Имя файла также может быть введено пользователем с клавиатуры: var name:string; f:text; begin writeln ('Введите имя файла:'); readln (name); assign (f,name); . Наконец, имя файла можно передать программе параметром командной строки (см. п. 5.3). После связывания следует открыть файл. Каждый файл может быть открыт только в одном из трех режимов -- для чтения данных, для записи новых данных (при этом, если файл уже существовал, его прежнее содержимое будет стерто) или для добавления данных в конец файла. Если требуется сначала прочитать данные из файла, а потом переписать этот же файл, следует открыть файл для чтения, после чтения закрыть его и вновь открыть для записи. Открытие файла выполняется одним из трех операторов: reset (f); -- открыть для чтения; rewrite (f); -- открыть для записи; append (f); -- открыть для добавления. Чтение или запись данных осуществляется знакомыми нам операторами read, readln, write и writeln, но первым параметром этих стандартных процедур указывается имя файловой переменной: var a,b,c:real; f1,f2:text; begin assign (f1,'read.txt'); assign (f2,'write.txt'); reset (f1); {открыли файл read.txt для чтения,} rewrite (f2); {а файл write.txt для записи} read (f1,a,b); {Прочитали 2 числа из файла read.txt} c:=(a+b)/2; writeln (f2,c:6:2); {записали значение c и перевод строки в файл write.txt} После того, как все операции с файлом выполнены, его следует закрыть, особенно если происходила запись или добавление данных: close(f); — закрыли файл, связанный с файловой переменной f. При работе с файлами могут возникнуть ошибки, связанные как с отсутствием нужного файла на диске, так и с проблемами чтения или записи (например, мы пытаемся открыть файл для записи на защищенном диске). Поэтому операторы открытия файла и чтения или записи данных следует защищать директивой компилятора {$I-}...{$I+}, а после оператора проверять статус операции ввода-вывода с помощью стандартной функции IoResult: var f:text; name,s:string; begin writeln ('Введите имя файла:'); readln (name); assign (f,name); {$I-}reset(f);{$I+} if IoResult<>0 then begin writeln ('Не могу открыть файл ',name, ' для чтения!'); writeln ('Нажмите Enter для выхода'); readln; halt; end; readln(f,s); writeln ('Первая строка файла:'); writeln (s); close(f); writeln ('Нажмите Enter для выхода'); readln; end. В дальнейшем мы для краткости не всегда будем выполнять эти проверки, но хороший стиль программирования предполагает, что в своих программах вы будете их делать. При чтении из файлов зачастую объем читаемых данных неизвестен заранее. Поэтому необходима функция, умеющая определять, прочитаны ли уже все данные: function Eof(var F : text) : boolean; -- возвращает true, если при чтении достигнут конец файла. function Eoln (var F : text) : boolean; -- возвращает true, если при чтении достигнут конец строки. Как правило, основной цикл чтения файла с заранее неизвестным количеством строк выглядит так: while not eof (f) do begin {операторы для чтения строк файла и работы с ними} end; При чтении из одного файла "смешанных" строковых и числовых данных следует проверять, действительно ли в нужных строках файла содержатся числа. Для этого можно использовать стандартную процедуру val. Как правило, формат файлов, понимаемых той или иной программой, выбирается программистом, и важно предусмотреть реакцию программы на ошибочный формат исходных данных. Допустим, наша программа представляет собой простейший телефонный справочник, включающий имена абонентов и по одному телефонному номеру на каждое имя. Формат файла, хранящего данные справочника, также выберем простейшим: Фамилия1 Номер1 Фамилия2 Номер2 и т. д., то есть, в строках 1, 3, 5, ... файла содержатся фамилии абонентов, а в строках 2, 4, 6, ... -- их номера телефонов. Примем также, что файл справочника называется phones.txt, существует и находится в той же папке, откуда запускается программа. Полный листинг программы приводится ниже. var f:text; name,phone,search:string; number,strings:longint; error:integer; found:boolean; begin assign (f,'phones.txt'); reset(f); writeln (Фамилия абонента для поиска:'); readln (search); strings:=1; {Счетчик прочитанных строк} found:=false; {Переключатель "найдено"-"не найдено"} while not eof(f) do begin readln (f,name); {Прочитали фамилию} readln (f,phone); {Прочитали номер} val (phone,number,error); {Пробуем номер-строку преобразовать в число} if error<>0 then begin {если это не удалось сделать - ошибка} writeln('Ошибка - нет номера телефона!', ' Номер строки=', strings); writeln ('Нажмите Enter для выхода'); reset (input); readln; halt; end; if name=search then begin writeln ('Телефон найден:',number); found:=true; break; end; strings:=strings+1; end; close (f); if found=false then writeln ('Телефон не найден!'); writeln ('Нажмите Enter для выхода'); reset (input); readln; end. Этой учебной программе недостает как умения редактировать открываемый ей справочник, так и гибкости при поиске -- например, она различает как разные символы строчные и прописные буквы во вводимой фамилии. |