В этом выпуске:
В программе из прошлого выпуска было кое-что незнакомое. Сейчас попробуем во всем разобраться.
Для начала надо сказать несколько слов о структуре самого файла. Каждый файл состоит из структурных элементов, определяющиеся типом файла. Каждому элементу файла можно присвоить какой-то порядковый номер, который, если файл не изменялся, будет иметь постоянное значение. Так файл можно сравнить с массивом данных с той разницей, что файл не имеет постоянный длины и заканчивается специальным символом маркером конца файла (EOF - End Of File). Он сигнализирует о том, что достигнут конец файла.
У каждого файла есть так называемый указатель. Он нужен для того, чтобы указывать на тот элемент, который будет обрабатываться (читаться или записываться). На каждый файл есть только один указатель, поэтому в каждый момент времени доступен только один элемент. После чтения или записи элемента указатель увеличивается на единицу, поэтому при циклической или цепочечной записи в файл вам можно не бояться за то, что какие-то данные окажутся "затертыми". Кроме этого в типизированных и нетипизированных файлах есть возможность самому устанавливать указатель на нужный элемент (но об этом в другой раз). В самом начале, когда файл только открыли, указатель устанавливается на самый первый элемент.
Один из циклов в программе предыдущего выпуска был организован следующим образом:
While not EOF(F2) do begin Read(F2, ch); Write(ch); end;
Алгоритм его работы: пока не достигнут конец файла выполнять тело цикла. Здесь EOF - логическая функция, которая возвращает истинное значение, если указатель находится за маркером конца файла, иначе она вернет ложное значение. В теле данного цикла производится чтение из файла, связанного с переменной F2, т.е. указатель модифицируется (увеличивается на единицу). Цикл работает до тех пор, пока указатель не окажется за маркером конца файла. В результате этого мы прочитаем весь файл.
Теперь поговорим о том, как производится чтение и запись данных из и в файл. Вначале рассмотрим типизированные и текстовые файлы, так как для нетипизированных файлов этот процесс заслуживает отдельного внимания.
Для этой операции файл должен быть открыт для записи. Запись осуществляется с помощью процедур Write и WriteLn. Первая применима как типизированным так и текстовым файлам. Вот их описание:
procedure Write(F, V1 [, V2,...,Vn ] );
Где F - переменная файлового типа, кроме нетипизированного. Vi (i=1…n) - записываемые данные. Их типы должны соответствовать типу переменной F. В случае, если параметр F опущен запись будет производиться на стандартное устройство вывода (обычно дисплей).
Процедура WriteLn отличается от предыдущей тем, что применяется только для текстовых файлов, она выполняет те же действия, что и Write, но при этом записывает в файл маркер конца строки. Т.е., грубо говоря, после записи данных в файл переходит к следующей строке файла. Ее описание:
procedure Writeln([ var F: Text; ] V1 [, V2, ...,Vn ] );
Где F и Vi (i=1…n) имеют тот же смысл, что и для процедуры Write.
Я думаю, вам не составит труда разобраться в следующей программе:
Uses CRT; const FName1 = 'Test1.pas'; FName2 = 'Test2.pas'; n = 5; var F : Text; st : string; i : byte; begin ClrScr; Assign(F, FName1); Rewrite(F); For i:=1 to n do Write(F, 'String ', i); Close(F); Assign(F, FName2); Rewrite(F); For i:=1 to n do WriteLn(F, 'String ', i); Close(F); end.
Созданные Файлы Test1.pas и Test2.pas вы можете просмотреть в любом текстовом редакторе, тогда и увидите отличия двух циклов в этой программе.
Чтение осуществляется с помощью процедур Read и ReadLn. Процедуру Read можно применить как к типизированным так и к текстовым файлам. Она считывает один или несколько компонентов из файла и присваивает их переменным, переданных ей в качестве параметра. Ее описание:
procedure Read(F , V1 [, V2,...,Vn ] );
здесь F и Vi (i=1…n) имеют тот же смысл, что и в процедуре Write.
Процедура ReadLn применяется только к текстовым файлам. Она выполняет те же действия, что и Read, с той лишь разницей, что после считывания переходит к следующей строке файла. Ее описание:
procedure Readln([ var F: Text; ] V1 [, V2, ...,Vn ]);
В случае, если параметр F не будет указан, то ввод данных будет производиться со стандартного устройства ввода (обычно клавиатура).
Наберите в окне редактора Pascal'я следующий текст, сохраните его (обязательно!) под именем Test3.pas и запустите. В результатах вы разберетесь сами.
< pre class="prog"> Uses CRT; const F1 = 'Test3.pas'; var F : Text; st : string; begin ClrScr; Assign(F, FName1); Reset(F); While not Eof(F) do begin ReadLn(F, st); WriteLn(F); end; Close(F); ReadKey; end.Кстати, если в цикле вместо ReadLn(F, st); написать Read(F, st);, то программа зациклится. А почему?
Теперь вам полностью должна быть понятна программа из прошлого выпуска.
Чтобы не было скучно приведу еще одну программку, в которой предлагаю разобраться вам самим:
Uses CRT; Type TString10 = string[10]; TString15 = string[15]; TFriend = record Name : TString10; SirName : TString15; Age : byte; end; const YesChars = ['Y', 'y', '', 'Ќ']; NoChars = ['N', 'n', ''', 'в']; FName1 = 'Record.pas'; FName2 = 'String.pas'; ch : char = #0; procedure Wait; begin If WhereX >=70 then begin GotoXY(1, 79); WriteLn('Press any key...'); ReadKey; ClrScr; end; end; procedure WaitKey; begin WriteLn('Are you wanting to continue?(Y/N) '); Repeat ch:=ReadKey; If ord(ch) = 0 then ch:=ReadKey; until (ch in NoChars) or (ch in YesChars); ClrScr; end; var st : string; FText : Text; FTFriend : file of TFriend; Friend : TFriend; begin ClrScr; WriteLn('Input data about your friend.'); Assign(FTFriend, FName1); Assign(FText, ''); Rewrite(FTFriend); Reset(FText); Repeat Write('Name : '); ReadLn(FText, FRiend.Name); Write('SirName : '); ReadLn(FText, FRiend.SirName); Write('Age : '); ReadLn(FText, FRiend.Age); Write(FTFriend, Friend); WaitKey; until ch in NoChars; Close(FTFriend); Reset(FTFriend); Assign(FText, FName2); ReWrite(FText); While not Eof(FTFriend) do begin Read(FTFriend, Friend); WriteLn(FText, Friend.Name); WriteLn(FText, Friend.SirName); WriteLn(FText, Friend.Age); end; Close(FText); ClrScr; Reset(FTFriend); WriteLn('Read from file of TFriend:'); While not Eof(FTFriend) do begin Read(FTFriend, Friend); WriteLn('Name : ', Friend.Name); WriteLn('SirName : ', Friend.SirName); WriteLn('Age : ', Friend.Age); WriteLn('====================='); Wait; end; Close(FTFriend); ReadKey; ClrScr; Reset(FText); WriteLn('Read from Text file.'); While not Eof(FText) do begin ReadLn(FText, st); WriteLn('Name : ', st); ReadLn(FText, st); WriteLn('SirName : ', st); ReadLn(FText, st); WriteLn('Age : ', st); WriteLn('======================'); Wait; end; ReadKey; Close(FText); end.
© Чарышкин Олег