Процедуры и функции для текстовых файлов

Лабораторная работа №9

Виды файлов. Файловая переменная

В Pascal имеются три вида файлов:

q текстовый файл (определяется типом text);

q типизованный файл (задается предложением file of Тип);

q нетипизованный файл (определяется типом file).

Для работы с файлами в программе необходимо определить файловую переменную (файловый тип) в разделе описаний программы

Например:

type filetype=text; { файловый тип }

var ftmp,f: filetype; { файловые переменные }

или

var f1,lst: text; f2: file;

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

Последовательность действий

Вне зависимости от файлового типа, любая программа работы с файлом должна выполнить следующие действия.

1. Определить переменные файлового типа (логические файлы).

2. Каждому из используемых физических файлов при помощи процедуры assign (в переводе — "назначить") поставить в соответствие переменную файлового типа. В Delphi вместо процедуры assign используется процедура assignfile.

3. Открыть файл — т. е. сделать существующий файл доступным для ввода и/или вывода. В случае ввода используется процедура reset (переустановка), во втором случае (вывод или совмещение ввода с выводом) используется процедура rewrite (перезапись). При открытии и создании файла для временного хранения его данных автоматически выделяется область в оперативной памяти компьютера, которая называется буфером файла.

Замечание Для того чтобы ускорить обмен информацией с внешними устройствами, в файловой системе используется механизм буферизации. Операционная система назначает каждому открываемому файлу так называемый обработчик файлов с определенным номером. Он осуществляет операции обмена данными через буфер ввода/вывода. При записи в файл вся информация сначала направляется в буфер и там накапливается до тех пор, пока он весь не заполнится. Только после этого (или при использовании специальной команды сброса) происходит передача данных на внешнее устройство. Аналогично при чтении из файла данные вначале считываются в буфер.

4. Обработать файл. Все предыдущие этапы носили подготовительный характер. Принцип обработки файлов любых типов состоит в следующем: данные из файла сначала считываются в оперативную память компьютера, для чего в программе назначаются переменные подходящих типов, и вся дальнейшая обработка ведется над этими переменными. В случае необходимости ее результаты записываются в новый файл или дописываются в уже существующий. Чтение (ввод) данных или их запись (вывод) выполняются при помощи инструкций read и readln, write и writeln, соответственно. Обратите внимание — первым параметром каждой из этих инструкций должна быть файловая переменная.

5. Закрыть файловую переменную и сохранить данные на диске после окончания работы с файлом. Это делает процедура close. Если файл закрыт, над ним нельзя выполнять никаких действий, пока он вновь не будет открыт.

Общие процедуры и функции

В Pascal существует ряд процедур и функций, применимых для файлов любых типов.

q Процедура assign(ФайловаяПеременная, ИмяФайла). Предшествует другим процедурам, т. к. ставит в соответствие физическому файлу на внешнем устройстве логический файл — файловую переменную (связывает их). ИмяФайла должно представлять собой выражение строкового типа. Дальнейшие операции с переменной ФайловаяПеременная будут выполняться над физическим файлом ИмяФайла. Процедуру assign недопустимо использовать для уже открытого файла. Прежде чем использовать файловую переменную повторно, необходимо закрыть файл с помощью процедуры close. После вызова assign связь файловой переменной с физическим файлом существует до тех пор, пока не будет выполнен другой assign для данной файловой переменной. Следовательно, файл можно повторно открыть без дополнительного использования процедуры assign даже после закрытия close.

q Процедура reset(ФайловаяПеременная) открывает существующий файл на чтение (открывает входной файл) и ставит указатель на начало первого элемента файла. При отсутствии внешнего файла с указанным именем возникает сообщение об ошибке File not found (Файл не найден). Если при чтении файла возникнет необходимость вернуть указатель в его начало, достаточно будет просто применить процедуру reset к этому файлу еще раз

q Функция ioresult — возвращает статус последней выполненной операции ввода-вывода (успешно она прошла или нет). Пример использования данной функции для обработки ошибок ввода-вывода уже рассматривался. При работе с файлами рекомендуется использовать ее при выполнении любого действия, которое может привести к ошибке. Например, при попытке открыть файл может оказаться, что файла с таким именем нет в текущем или заданном каталоге. Стандартный способ обработки такой ошибки — аварийная остановка программы с сообщением File not found (файл не найден). Обработка функции ioresult позволит выполнить проверку существования файла на диске более гибко. В Delphi для этих целей имеется более удобный способ — стандартная функция fileexists.

q Процедура rewrite(ФайловаяПеременная) — создает и открывает новый (выходной) файл для последующей записи данных. После ее успешного выполнения файл готов к записи в него первого элемента.

Обратите внимание — использование rewrite требует особой аккуратности. Если физический файл с указанным именем уже существует, то он удаляется, и на его месте создается новый пустой файл с тем же именем. Для предотвращения потери информации на практике необходимо создавать резервные копии файлов, над которыми могут производиться опасные действия.

q Процедура close(ФайловаяПеременная). Используя процедуру close, программист должен закрыть файл, после того как в программе будет завершена его обработка. В противном случае может произойти потеря данных. При закрытии внешний (физический) файл обновляется и его автоматически завершает символ конца файла. Впоследствии ФайловаяПеременная может быть связана с другим (или вновь с тем же самым) физическим файлом.

q Процедура rename(ФайловаяПеременная, ИмяФайла) — используется для того, чтобы переименовать неоткрытый внешний файл любого типа. Новое имя задается строкой ИмяФайла.

q Процедура erase(ФайловаяПеременная) — удаляет неоткрытый внешний файл любого типа, задаваемый параметром ФайловаяПеременная

Обратите внимание —процедуры rename и erase нельзя использовать для открытых файлов. Их необходимо предварительно закрыть. Если файл не существует, возникает ошибка выполнения программы.

q Логическая функция eof(ФайловаяПеременная) — выполняет проверку, не достигнут ли конец файла (End Of File) при чтении из него данных. Функция возвращает true, если конец файла обнаружен и указатель текущей позиции находится в конце файла за его последним символом. Это значит, что последний элемент в файле уже прочитан или файл после открытия оказался пуст. В противном случае функция возвращает false.

Замечание

Функция eof находит широкое применение в задачах обработки файлов, поскольку позволяет задать условие выполнения цикла для чтения данных из файла. Особенно она важна для текстовых файлов. Если параметр ФайловаяПеременная отсутствует, подразумевается консоль.

В качестве примера создадим программно новый текстовый файл с именем file01.txt, содержащий одну строку текста, которая записывается в него в виде текстовой константы. Для чтения используем строковую переменную str.

var f: text; str: string;

begin

assign(f,'file01.txt'); rewrite(f);

writeln(f,'Этот простой текстовый файл содержит строку текста');

close(f);

assign(f,'file01.txt'); reset(f);

readln(f, str);

close(f);

writeln('Проверка ввода/вывода в файл:'); writeln(str);

end.

Текстовые файлы

Компонентами текстовых файлов являются символы, организованные в виде последовательности строк произвольной длины, что не позволяет считать их просто набором символов char.

Каждая строка в текстовом файле оканчивается составным символом "конца строки", который является объединением двух символов: символа #13 (CR) — возврат каретки (carridge return) и символа #10 (LF) — перевод строки (line feed). Для составного символа вводят обозначение eoln (End Of LiNe). Символ eoln нельзя присвоить переменной типа char. Однако его можно распознать с помощью функции eoln.

Текстовый файл — это последовательность символов, сгруппированных в строки, заканчивающиеся специальным символом eoln.

В конце любого файла, в том числе и текстового, ставится символ #26 (SUB) — конец файла eof (End Of File).

Замечание

Текстовый файл можно подготовить и прочитать при помощи обычного текстового редактора, который не использует операции форматирования текста. Надо только помнить, что в DOS и Windows используются разные кодировки для русских букв, поэтому при работе в Turbo Pascal нужно пользоваться редактором для DOS (встроенный редактор этой системы вполне годится). При работе с Delphi или другой 32-разрядной системой файл может быть подготовлен при помощи приложения "Блокнот". Программа MS Word позволяет сохранить текстовые файлы с различной кодировкой (при этом теряется форматирование) с помощью команды Файл | Сохранить как. Далее следует выбрать текст DOS (*.txt)или только текст (*.txt).

Объявление текстового файла в программе осуществляется заданием файловой переменной типа text (текст) в виде:

typeИмяТипа = text;

var ФайловаяПеременная : ИмяТипа;

или

var ФайловаяПеременная : text;

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

Процедуры и функции для текстовых файлов

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

Открытие текстового файла можно произвести тремя способами. Два из них являются стандартными: reset и rewrite. Процедура reset открывает текстовые файлы только для чтения. Процедура rewrite перезаписывает их. Новая процедура append позволяет дополнять файл новыми записями.

q Процедура append(ФайловаяПеременная). Она открывает существующий файл для дозаписи. Указатель ставится не в начало, а в конец файла, куда и будут дописываться новые компоненты. ФайловаяПеременная текстового типа предварительно должна быть связана с внешним файлом с помощью процедуры assign. Процедура append применима только к текстовым файлам. Если файл ранее уже был открыт с помощью reset или rewrite, использование append приведет к закрытию этого файла и к повторному открытию, но уже для добавления элементов

После обращения к append текстовый файл доступен только по записи, и функция eof всегда принимает значение truе. После вызова reset или rewrite функция eof принимает значение true, только если файл пуст, иначе — false.

q Процедуры чтения:

read(ФайловаяПеременная, x1, x2,...,xN);

readln(ФайловаяПеременная);

readln(ФайловаяПеременная, x1, x2,...,xN);

где x1, x2,...,xN — список ввода, содержащий имена переменных разных типов (integer, real, char, string), значения которых процедура read считывает из текстового файла, начиная чтение с элемента, на который установлен текущий указатель. Файловая переменная имеет тип text.

Процедура readln выполняет те же действия, что и read, и дополнительно — переход к новой строке.

Вызов readln(ФайловаяПеременная) без параметров приводит к перемещению текущей позиции файла на начало следующей строки (если она имеется, в противном случае происходит переход к концу файла). Так можно пропускать строки.

При выборе между read и readln для выполнения чтения из текстового файла необходимо помнить, что после считывания последней переменной списка ввода процедура readln пропускает оставшуюся часть строки до eoln и обязательно переходит к следующей строке текстового файла, даже если из текущей строки прочитаны еще не все символы. Следующее обращение к очередной процедуре read или readln начнется с первого символа новой строки. В отличие от readln процедура rеаd не делает после считывания пропуск до следующей строки. Поэтому она непригодна для чтения последовательности строк, поскольку не дает возможности продвинуться дальше первой строки. Таким образом, для ввода следующих друг за другом строк текста необходимо использовать readln.

q Процедуры записи:

write(ФайловаяПеременная, y1, y2,...,yN);

writeln(ФайловаяПеременная);

writeln(ФайловаяПеременная, y1, y2,...,yN);

где y1, y2,...,yN — список вывода, содержащий выводимые выражения разных типов (integer, real, char, string, boolean), значения которых должны быть записаны в файл, начиная с позиции текущего указателя. Возможно использование формата вывода. Файл должен быть открыт для вывода.

Процедура writeln выполняет те же действия, что и write, и дополнительно вставляет признак конца строки eoln.

Обратите внимание — особенность использования текстовых файлов состоит в том, что процедуры чтения read (readln) и записи write (writeln) разрешают работать со значениями различных типов. Последовательность символов, прочитанная из файла, автоматически преобразуется к значению типа той переменной, которая используется в списке ввода read (readln). При записи в файл происходит автоматическое преобразование значений переменных списка вывода write (writeln) к символьному виду.

Например, при выполнении фрагмента программы

var f1: text; a,b,c: real;

readln(f1,a,b,c);

процедура readln выполняет чтение из очередной строки файла f1 последовательности цифр, затем интерпретируемой как три вещественных числа, значения которых будут присвоены переменным a, b, c. Если вместо ожидаемой последовательности чисел в файле содержится любая другая последовательность символов, возникает ошибка ввода/вывода. Считывание значений символьного и строкового типов из текстового файла — более безопасная операция, чем чтение данных числового типа. Если длина строки при чтении превышает длину, максимально допустимую для строковой переменной, то она усекается.

q Функции проверки конца строки и файла:

· кроме использования функции eof, принимающей значение true, если файл исчерпан, при работе с текстовыми файлами необходимо уметь проверять также и конец строки. Для контроля используется функция eoln(ФайловаяПеременная), принимающая значение true, если указатель текущей позиции находится на маркере конца строки (CR/LF), иначе — false. Если eof — true, то и eoln — true.

· Функция seekeoln(ФайловаяПеременная) аналогична функции eoln, но в отличие от нее, пропускает пробелы и позиции табуляции перед проверкой на конец строки. Функцию можно использовать только для открытых текстовых файлов.

· Функция seekeof(ФайловаяПеременная) аналогична eof, но пропускает пробелы, позиции табуляции и маркеры конца строки перед проверкой на конец файла. Функцию можно использовать только для открытых текстовых файлов.

Обратите внимание — функции seekeof и seekeoln удобно использовать при чтении числовых данных из текстового файла, когда необходимо пропустить разделяющие числа пробелы или знаки табуляции (см. листинг ).

Наши рекомендации