Стандартные процедуры и функции обработки файлов

Оглавление

Файлы. Файловые переменные. Ошибка! Закладка не определена.

Стандартные процедуры и функции обработки файлов. 3

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

Файлы без типа (нетипизированные файлы) 6

Контрольные вопросы.. 8

Задание. 8

Лекция №24

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

Понятие «файл» обычно связывают с информацией на устройствах внешней памяти. В Паскале понятие файла употребляется в двух смыслах:

• как поименованная информация на внешнем устройстве (внешний файл);

• как переменная файлового типа в Паскаль-программе (внутренний файл).

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

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

Структура описания файловой переменной:

Var <имя переменной>: File Of <тип элемента>;

где <тип элемента> может быть любым, кроме файлового типа.

Например:

Var

Fi:File Of Integer;

Fr:File Of Real;

Fc: File Of Char;

Файл можно представить как последовательную цепочку элементов (эл.), пронумерованных от 0, заканчивающуюся специальным кодом, называемым маркером конца (<м. к.>):

эл.0 эл. 1 ….. эл. N м.к.

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

Для того чтобы начать запись в файл, его следует открыть для записи. Это обеспечивает процедура REWRITE (FV); где FV — имя файловой переменной. При этом указатель устанавливается на начало файла. Если в файле есть информация, то она исчезает. Схематически выполнение процедуры REWRITE можно представить так:

До:

эл.0 эл. 1 ….. эл. N м.к.

 

REWRITE(FV,V);

После:

м.к.  

­

Стрелка внизу отмечает позицию указателя.

Запись в файл осуществляется процедурой WRITE (FV, V); где V — переменная того же типа, что и файл FV. Запись происходит туда, где установлено окно (указатель). Сначала записывается значение, затем указатель смещается в следующую позицию. Если новый элемент вносится в конец файла, то сдвигается маркер конца. Схема выполнения оператора:

До:

эл.0 эл. 1 ….. эл. N м.к.

­

WRITE(FV,V);

После:

эл.0 эл. 1 ….. эл. N V м.к.

­

Пример 1. В файловую переменную Fx занести 20 символов, последовательно вводимых с клавиатуры.

Var Fx: File Of char;

X: char; I: Byte;

Begin

Assign(FX,’d:1.dat’);

Rewrite(Fx);

For I:=1 To 20 Do

Begin

Write ('?'); ReadLn(X);

Write(Fx,X)

End;

Close(fx)

End.

Для чтения элементов файла с его начала следует открыть файл для чтения. Это делает процедура Reset (FV). В результате указатель устанавливается на начало файла. При этом вся информация в файле сохраняется. Схема выполнения процедуры:

До:

эл.0 эл.1 ….. эл.N м.к.

­

RESET(FV);

После:

эл.0 эл.1 ….. эл.N м.к.

 

 

­

Чтение из файла осуществляется процедурой READ (FV, V); где V — переменная того же типа, что и файл FV. Значение текущего элемента файла записывается в переменную v; указатель смещается к следующему элементу.

До:

эл.0 эл.1 ….. эл.К эл.К+1 …. эл.N м.к.

­

READ(FV,V);

После:

эл.0 эл.1 ….. эл.К эл.К+1 …. эл.N м.к.

­

Доступ к элементам файла может быть последовательным или прямым. В стандартном Паскале реализован только последовательный доступ.

Принцип последовательного доступа: для того чтобы прочитать n-ю запись файла, сначала нужно прочитать все предыдущие записи с 1-й по (n-1)-ю.

Пример 2. В переменной х получить 10-й элемент символьного файла Fx.

Program A;

Var Fx: File Of char;

X: char;

Begin

….

Reset(Fx);

For I:=l To 10 Do Read(Fx,X)

….

End.

Функция Eof (FV) проверяет маркер конца файла (end of file). Это логическая функция, которая получает значение true, если указатель установлен на маркер конца, в противном случае — false.

Пример 3. Просуммировать все числа из файла целых чисел Fx.

 

…..

Reset(Fx);

Sx:=0;

While Not Eof(Fx) Do

Begin

Read(Fx,X);

Sx:=Sx+X

End;

……

To же самое с помощью цикла Repeat можно делать следующим образом:

Repeat

Read(Fx,X);

Sx:=Sx+X

Until Eof(Fx);

Во втором варианте возможна ошибка чтения, если файл Fx пустой. Первый вариант от такой ошибки застрахован, поэтому он более предпочтителен.

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

Стандартные имена логических устройств определяются операционной системой, в среде которой работает Паскаль. В системе MS DOS определены следующие имена:

CON (консоль) — логическое устройство, связанное при вводе с клавиатурой, при выводе — с экраном;

PRN (принтер) — логическое имя файла, связанного с устройством печати;

AUX — логическое имя коммуникационного канала, который используется для связи ПК с другими машинами;

INPUT — логическое имя стандартного устройства ввода, связанного с клавиатурой; при этом вводимые с клавиатуры символы отражаются на экране дисплея;

OUTPUT — логическое имя стандартного устройства вывода а экран.

Для организации связи между файловой переменной и внешним файлом в Турбо Паскале используется процедура назначения Assign.

Стандартные процедуры и функции обработки файлов

ASSIGN (<имя файла>,<имя файла на носителе>); – процедура устанавливает связь между именем файловой переменной и именем файла на… RESET(<имя файла>); – процедура открытия существующего файла для чтения… REWRITE(<имя файла>); – процедура открытия создаваемого файла для записи. Если файл с таким именем уже…

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

  S1 S2 … Sk1 к.с.   S1 S2 … Sk2 к.с.   … Каждый символ представлен во внутреннем коде ASCII и занимает 1 байт.… К текстовым файлам возможен только последовательный доступ. С текстовыми файлами работают различные редакторы текстов.…

BEGIN

WRITE(‘ВВОД ИМЕНИ ВХОДНОГО ФАЙЛА:’);

READLN(NAME);

ASSIGN(F1,NAME);

WRITE(‘ВВОД ИМЕНИ ВЫХОДНОГО ФАЙЛА:’);

READLN(NAME);

ASSIGN(F2,NAME);

RESET(F1); REWRITE(F2);

WHILE NOT EOF(F1) DO

BEGIN

READLN(F1,POLE);

WHILE POS(‘DC-101’, POLE) <> 0 DO

BEGIN

PZ:= POS(‘DC-101’, POLE);

DELETE(POLE,PZ+3,1);

INSERT(‘2’,POLE,PZ+3);

END;

WRITELN(F2,POLE)

END;

CLOSE(F1);

CLOSE(F2);

END.

 

Здесь читаются последовательно строки из входного файла и в каждой строке в номере группы заменяется символ 1 на 2. Скорректированные строки выводятся в новый файл.

Пример 5. Пусть файл с именем Note. txt содержит некоторый текст. Требуется подсчитать количество строк в этом тексте.

Var Note: Text; К: Integer;

Begin Assign(Note,'Note.txt') ;

Reset(Note);

K:=0;

While Not Eof (Note) Do

Begin

ReadLn(Note); K:=K+1

End;

WriteLn('Количество строк равно',К);

Close(Note)

End.

Используемый здесь оператор ReadLn (Note) «пролистывает» строки из текстового файла Note, не занося их в какую-либо переменную.

Пример 6. В текстовом файле Note. txt определить длину самой большой строки.

Var Note: Text;

Мах,К: Integer; С: Char;

Begin

Assign(Note,'Note.txt');

Reset(Note);

Max:=0;

While Not Eof(Note) Do

Begin

K:=0;

While Not Eoln(Note) Do

Begin

Read(Note,С); K:=K+1

End;

If K>Max Then Max:=K;

ReadLn(Note)

End;

WriteLn('Наибольшая строка имеет', Max,'знаков');

Close(Note)

End.

Здесь каждая строчка прочитывается посимвольно, при этом в переменной К работает счетчик числа символов в строке. В переменной Мах отбирается наибольшее значение счетчика.

Файлы без типа (нетипизированные файлы)

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

BEGIN

WRITE(‘ИМЯ ВХОДНОГО ФАЙЛА ’);

READLN(NAME);

ASSIGN(FROMF, NAME);

WRITE(‘ИМЯ ВЫХОДНОГО ФАЙЛА ’);

READLN(NAME);

ASSIGN(TOF,NAME);

RESET(FROMF, 1); {существующий файл}

REWRITE(TOF, 1);{новый файл}

REPEAT

BLOCKREAD(FROMF, BUF, SIZEOF(BUF), NR);

BLOCKWRITE(TOF, BUF, NR, NWR);

UNTIL (NR = 0) OR (NWR <> NR);

CLOSE(FROMF);

CLOSE(TOF);

END.

В примере программы при открытии файла без типа в вызове процедуры RESET указана длина записи равная 1. В этом случае при копировании файла не будут записаны лишние символы в новый файл.

 

Пример 8. Допустим имеем такой файл: dЦHello! Здесь: d - ASCII 100, Ц - ASCII 150 , Hello! - строка из 6-ти символов. Организовать чтение из файла с выводом на экран.

type R = record

A: Byte;

C: Array[1..6] of Char; end;

var F: File; I: Byte; Rec: R; Result: Word;

Begin

Assign(F, '1.txt'); { связываем файл с переменной}

{$I-}

Reset(F, 1);

{$I+}

if IOResult<>0 then Halt;

BlockRead(F, I, Sizeof(I), Result);

BlockRead(F, Rec, Sizeof(Rec), Result); Writeln(I);

Writeln('Rec values: '); Writeln('A: ', Rec.A); Writeln('S: ', Rec.C);

Readln; Close(F);

End.

В примере функция SIZEOF принимает в качестве параметра любую переменную и возвращает ее размер в байтах. Размер переменных стандартных типов (Integer, Byte....) можно найти в таблицах типов. Поэтому SIZEOF иногда очень выручает, упрощая работу. Дополнительный параметр процедуры RESULT указывает размер буфера, который используется для передачи данных. Буфер по умолчанию равен 128 байт. Если его явно не указывать, то Паскаль устанавливает это значение.

Пример 9. Сформировать данные для записи в файл.

Uses Crt;

type R = record

A: Integer;

B: Word; end;

var F: File;

Result: Word;

C: Char;

I: Integer;

S: String;

Rec: R;

Begin

ClrScr;

{ считываем и задаем исходные данные }

Write('Enter CHAR: '); Readln(C);

Write('Enter INTEGER: '); Readln(I);

Write('Enter STRING: '); Readln(S);

Randomize;

Rec.A := Random(1000); Rec.B := Random(1000);

Writeln('Rec.A: ', Rec.A);

Writeln('Rec.B: ', Rec.B);

Readln;

{ выполняем действия по записи в файл }

Assign(F, '1.txt');

ReWrite(F, 1);

BlockWrite(F, C, SizeOf(C)+SizeOf(I)+255+SizeOf(Rec), Result);

Close(F);

End.

В процедуре BLOCKWRITE использовалось целое выражение в качестве указания размера записываемого буфера. Составлено оно из суммы 3х результатов функции SIZEOF и числа 255, которое является длиной строки S.

 

Пример11. Использование псевдографики. Это обычные символы, которые имеются в стандартном наборе ASCII.

Program Border;

Uses Crt;

Procedure MakeWindow(X, Y, X1, Y1: Byte);

Var I: Byte;

Begin

GotoXY(X, Y); Write(#201); GotoXY(X1, Y); Write(#187);

GotoXY(X, Y1); Write(#200); GotoXY(X1, Y1); Write(#188);

For I := X+1 to X1-1 do

Begin GotoXY(I, Y); Write(#205);GotoXY(I, Y1); Write(#205); end;

For I := Y+1 to Y1-1 do

Begin GotoXY(X, I); Write(#186); GotoXY(X1, I); Write(#186); end;

End;

var B: Byte;

Begin

ClrScr;

Writeln('201: ', #201); {вывод символа по его коду} Writeln('205: ', chr(205));{возвращает символ, номер которого в ASCII таблице… Writeln('187: ', chr(B)); { }

Readln;

End.

 

Контрольные вопросы

1. Дать определение понятию файловой переменной.

2. Стандартные процедуры и функции обработки данных файла.

3. Формат файловой переменной для текстовых файлов. Перечислить процедуры и функции для работы с текстовыми файлами.

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

Задание

  1. Создайте процедуру создания окна с заголовком: наподобие тех, которые использует сам Turbo Pascal. Естественно, без служебных символов и областей, просто заголовок, расположенный посередине.
  2. Создайте программу "Записная книжка", с возможностью сохранения информации в файл.