В этом выпуске:
В программе из прошлого выпуска было кое-что незнакомое. Сейчас попробуем во всем разобраться.
Для начала надо сказать несколько слов о структуре самого файла. Каждый файл состоит из структурных элементов, определяющиеся типом файла. Каждому элементу файла можно присвоить какой-то порядковый номер, который, если файл не изменялся, будет иметь постоянное значение. Так файл можно сравнить с массивом данных с той разницей, что файл не имеет постоянный длины и заканчивается специальным символом маркером конца файла (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.
© Чарышкин Олег