В.Г. Абрамов, Н.П. Трифонов, Г.Н. Трифонова - Введение в язык Паскаль (1107618), страница 51
Текст из файла (страница 51)
В большинстверешаемых задач, в которых используются файлы, необходимо последовательно перебрать компоненты и произвести определенную их обработку.В таком случае необходимо иметь возможность определять, указывает лиокно на какую-то компоненту файла, или оно уже вышло за пределы файлаи указывает на маркер конца файла. Для определения этого факта в паскале введена в употребление стандартная логическая функция с именемeof (от end of file ), обращение к которой имеет вид eof(f).Значение этой функции равно true, если окно указывает на маркерконца файла с именем f (т.е. на позицию, следующую за последней компонентой файла), и значение false в противном случае.Следует сразу предостеречь от характерной ошибки при работе сфайлами: если значение функции e o f ( f ) равно true, то обращение к про217цедуре чтения из этого файла приведет к ошибке, т.е.
недопустимо использование оператора процедуры, например read(f, d), если eof(f) = true.П р и м е р 12.1. Имеется файл с именем Шифртекст, состоящий изцелых чисел, каждое из которых находится в диапазоне от 65 до 90 и представляет собой код литеры. Необходимо напечатать содержимое файлав расшифрованном текстовом виде (в виде последовательности литер).Считать,"последовательные целые числа из диапазона 65..90 кодируютпоследовательные большие буквы латинского алфавита от А до Z.{Пример 12.1. Леонов М.В. Ф-т ВМиК МГУ 3.3.87 г.Расшифровка и печать текста из заданногочислового Файла}{Пример работы с Файлами}program расшифровкаШифртекст,output);typeкод—65..90;буква='А'..
'Z' ;шифр=-?11е of код;varк: код; у.: буква;Шифртекст: шифр;begin {установка Файла с именем Шифртекст в режимсчитывания}reset(Шифртекст);while not eo-f (Шифртекст) dobegin {чтение очередного кода}read (Шифртекст , >;) ;{расшифровка кода и замена его на букву}case к o-f,65: у: = 'А ; 66: У68: у: = ' D69: У71: у: = ' G 5 72: У==='В 5 67: У'Е ; 70: УН.
5 73: У74: у: = ' J ; 75: У - 'К 577: у: = 'М 5 78: У « N80: у: = •Р ; 81: У = Q «83: у: = ' S 5 84: У = Т 586: у: = ' V ; 87: У = Ы ;89: у: = ' Y ; 90: Уend;end218end.'С=F=I76: У = Ч.79: У г.. 082: У = R85: У88: Уг{печать расшифрованной буквы}wr i t е (у >==и=XВ приведенном выше примере использована довольно типичная конструкция языка паскаль при обработке файлов, которая включает в себяоператор цикла с предусловием. В качестве предусловия используется логическое выражение not eof (Шифртекст) (т.е. пока не конец файла с именемШифртекст), а в теле цикла ведется обработка компонент файла.12.2. Буферная переменная и ее использованиеВспомним стандартную процедуру чтения компоненты файла read (f, v ) .Результат выполнения этого оператора процедуры состоит из двух действий: первое — это копирование значения компоненты файла f, на которуюуказывает окно, и присваивание этого значения переменной v; второе —передвижение окна на следующую позицию файла.
В некоторых задачахудобно иметь возможность производить эти два действия отдельно.Вот для таких приложений и удобно использовать буферные переменныефайлов.Предположим, что файл f установлен в режим чтения. Тогда буфернойпеременной будем называть конструкцию f t , т.е. к имени файловой переменной справа приписывается символ t. Эту переменную не надоописывать в разделе описания переменных, она определяется автоматическис введением в употребление файловой переменной.
Тип этой буфернойпеременной совпадает с типом компонент файла. С значением этой буферной переменной можно выполнять любые операции, которые можно выполнять с любой другой переменной — естественно, с учетом тех ограничений,которые накладывает тип значений компонент соответствующего файла.В режиме чтения значением переменной ft всегда является та компонентафайла, на которую указывает окно. При выполнении оператора процедурыreset(f), где f — некоторая файловая переменная, происходит не толькоустановка окна на начало файла f, но и присваивание значения первой компоненты файла буферной переменной f t , что можно изобразить следующимобразом:токноftВЕсли выполнен оператор процедуры reset(f), а файл f в действительностипуст, т.е.
значение стандартной функции e o f ( f ) равно true, то значение буферной переменной ft считается неопределенным. Окно файла в этом случае сразу указывает на маркер конца файла.Для передвижения окна на следующую компоненту непустого файлапредусмотрена стандартная процедура с именем get, параметром которойявляется имя файловой переменной. Результат выполнения этой процедурысостоит в передвижении окна на следующую позицию файла с присваиванием значения этой следующей компоненты буферной переменной.В случае, если окно файла указывает на последнюю компоненту и выполняется процедура get, то после выполнения этой процедуры окно файлабудет указывать на маркер конца файла (значение функции eof будетравно true), а значение буферной переменной считается неопределенным.В режиме записи значений в файл, который устанавливается после выполнения процедуры rewrite, буферная переменная выполняет роль поставщика значений компонент файла.
Стандартная процедура put(f) производитзапись в файл f в качестве очередной компоненты значение буферной переменной ft (после чего значение ft становится неопределенным) и сдвигаетокно на следующую позицию, в которую помещается маркер конца файла,тем самым подготавливаясь для записи очередной компоненты. Такимобразом, прежде чем выполнить оператор p u t ( f ) , необходимо задатьзначение буферной переменной f t .
Это можно сделать, например, спомощью оператора присваивания ft := е, где е - выражение того же типа,что и компоненты файла. Действия стандартной процедуры put приусловии, что f — это файл из целых чисел, можно изобразить так:состояние файла f и буферной переменной ft до выполнения процедуры p u t ( f )ftИf356 78 23tокноftпроцедуры p u t ( f•f35678 2317tокноОтметим следующее свойство: если файл f находится в режиме записи,то значение функции eof(f) всегда равно true.П р и м е р 12.2. Заданы два целочисленных файла f и g одинаковойдлины. Образовать третий целочисленный файл h, компоненты которогоопределяются по правилу h(- = max(f,-, g,).{Пример 12.2.Ершова Н.В.
Ф-т ВМиК МГУ 8.3.87 г.По заданным целочисленным Файлам -f и добразовать Файл h, где hi=шан<fi,gi)}{Использование процедур get и put.}program максэлем<-f,g,h);var+ , g , h: -file o-f integer;beginreset<f); reset(g); rewrite(h);while not eo-f(-f) dobegin i-f -ft>g + then h + :=-ft else ht:=gt;put <h> ; get(-f); get(g)endend.220Характерная черта приведенного выше примера состоит в том, что в немисключены вспомогательные переменные целого типа за счет использованиябуферных переменных и стандартных процедур put и get.Если вспомнить введенные ранее стандартные процедуры read иwrite, то следует сказать о полной эквивалентности действий операторапроцедуры read(f,v) и следующего составного оператора:begin v:=-ft; get<f) endа также оператора процедуры write(s, w) и составного оператора:begin s+:=w; put(s) end12.3.
Текстовые файлыСреди всех файловых типов значений вфайлы. Этот тип значений так широкопринят в качестве стандартного тинавообще говоря, представляет из себяэтот файловый тип не эквивалентенобразом:паскале особо выделены текстовыеиспользуется в программах, что онс именем text. Текстовый файл,последовательность литер, однакотипу Т, задаваемому следующимtypeТ = file of char;Дело в том, что литерный файл тина Т - это единая последовательностьлитер. Между тем довольно часто возникает необходимость разбить входящую в файл последовательность литер на отдельные порции, т.е. строки(подобно тому, как делится на строки текст программы или книги),причем назначение и правила обработки разных строк могут быть различными.Особенность текстовых файлов как раз и состоит в том, что содержащиеся в них последовательности литер могут быть разбиты на строки(хотя это и необязательно). Строки могут быть разной длины, в томчисле и пустыми.
В конец каждой строки помещается специальная управляющая литера, называемая "конец строки". Эта управляющая литера,естественно, не включена в стандартный тип char и не имеет графическогопредставления. Внутреннее представление этой литеры определяется реализацией, а существенным с точки зрения языка является лишь то, чтос ней связана логическая функция с именем eoln (от слов end of line).Функция eoln(s) принимает значение true, если окно указывает на тотэлемент файла s, который является признаком конца строки, и значениеfalse в остальных случаях. Если eoln(s) равно true, то буферной переменной st присваивается в качестве значения литера пробел (но не "конецстроки" — такого значения типа char не существует). Следовательно, пробел может быть значением буферной переменной в двух случаях:когда очередная компонента текстового файла действительно являетсяпробелом (но при этом значение функции eoln равно false), и когда окноуказывает на элемент файла "конец строки" (при этом значение функцииeoln равно true).Для записи в файл признака конца строки служит стандартная процедура writeln.Тип с именем text в программе описывать нельзя, а переменные этогостандартного типа вводятся в употребление обычным образом, напримерvars,d: textСтандартные файлы input и output, предназначенные для ввода и вывода, являются текстовыми файлами.