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

В DOS текстовые файлы физически не отличаются от любых других, но в Object Pascal различия существенны. Элементами текстовых файлов являются символы, объединенные в строки, но текстовый файл это не file of Char или file of String. Каждая строка заканчивается в текстовом файле символом возврата каретки CR=#13 и перевода строки LF=#10. Заканчивается текстовый файл признаком конца файла SUB=#26. Работа с текстовыми файлами очень напоминает работу с консолью. Чтение из текстовых файлов очень похоже на ввод с клавиатуры, а запись в файл напоминает вывод на экран. Указатель в текстовом файле имеет много общего с текстовым курсором.

Доступ к элементам текстового файла организуется последовательно. Указатель при считывании очередного элемента файла перемещается к следующему элементу. Для записи в текстовый файл или чтения их него можно использовать процедуры Read, Readln, Write, Writeln. В качестве первого параметра в этих процедурах указывается файловая переменная, например:

Read(fp, a, s);

Здесь происходит присваивание переменным a и s значений двух очередных элементов их файла, связанного с файловой переменной fp.

При выполнении программы на Object Pascal автоматически открываются два стандартных файла текстового типа. Стандартные файлы имеют имена файловых переменных Input и Output. Стандартная файловая переменная Input представляет собой доступный только для чтения файл для ввода символов с клавиатуры. Вторая файловая переменная Output связана с доступным только для записи стандартным устройством вывода символов и графических элементов на экран монитора. Обращение к файлам Input и Output происходит автоматически, без каких-либо дополнительных средств с помощью операторов Read, Readln, Write, Writeln. Файловая переменная (Input и Output) в этих процедурах не указывается, если работа ведётся со стандартным файлом.

Приведём пример переназначения стандартных файлов (т.е. ввод с клавиатуры и вывод на экран) дисковым файлам.

program p12_13;

var

N, M: longint;

……….

begin

assign(Input, 'c:\test.txt');

reset (Input) ;

…………….

Read(N, M);

……………..

close (Input);

…………………

assign(Output, 'c:\test_rez.txt');

rewrite(Output) ;

………..

Write(N, M);

……………….

close (Output) ;

end.

Таким образом, эта программа введёт значения переменных N и M из текстового файла test.txt и выведёт результаты работы (значения переменных N и M) в файл test_rez.txt .

Файловая переменная для текстового файла описывается следующим образом:

 

<список идентификаторов файловых переменных> : Text;

 

При работе с текстовым файлом, файловую переменную связывают с именем файла, обращаясь к процедуре Assign, а открывают для чтения и записи процедурами Reset и Rewrite соответственно. Процедура Reset открывает текстовый файл только для чтения. Открытый файл закрывается с помощью процедуры Close.

В текстовый файл, как и на экран, мы можем выводить значения выражений практически любого типа. При выводе значений операторами Write и WriteLn можно пользоваться стандартными средствами форматирования данных.

Примеры:

Write(f, x: 6: 4);

Writeln(g, 'Т=' , f 5: 2) ;

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

Примеры:

program p12_14;

{ Программа выводит в текстовый файл матрицу n*m }

const

n= 3;

m= 4 ;

var

Т: array[1.. n, 1.. m] of real;

f: Text; { описываем файловую переменную }

S: String;

i, j: integer;

begin

Writeln('введите элементы матрицы ', n, '*', m) ;

For i:= 1 to n do

for j : = 1 to m do

begin

Write ('T[' , i , '*,' , j, '] =') ;

Readln(T[i, j ] ) ;

end;

Write('введите имя файла:');

Readln(s);

Assign(f, s); { связываем файловую переменную с именем файла }

{$i-}

Rewrite(f); { открываем текстовый файл для записи }

If IOResult <> 0 then

begin

Writeln('Ошибка при открытии файла');

Halt;

end;

{$i+}

for i:= 1 to n do

begin

for j := 1 to m do

Write(f, T[i, j] : 8 : 3) ;

Writeln(f) ;

end;

Close (f);

end.

 

program p12_15;

{ Программа читает матрицу n*m из текстового файла }

const

n = 3;

m = 4;

var

Т: array[1.. n, 1.. m] of real;

f : Text;

S : String;

i, j : integer;

begin

Write('Введите имя файла:');

Readln(s);

Assign(f, s);

{$i-}

Reset(f); { Открываем текстовый файл для чтения }

if lOResult <> 0 then

begin

Writeln('Ошибка при открытии файла');

Halt;

End;

{$i+}

for i:= 1 to n do

begin

for j:= 1 to m do

begin

Read(f, T[i, j] ) ;

Write(T[i, j] : 8 : 3);

end;

Writeln;

End;

Close(f);

end.

 

Задача. Дан текстовый файл, создать второй текстовый файл, уплотнив первый, заменяя в каждой строке серии из двух или более пробелов (32 - ASCII) одним пробелом.

program p12_16;

var

fl, f2: Text;

S: String;

Sl, S2: String;

{ функция параметром получает неуплотненную строку, а

возвращает уплотненную }

function Uplot(S: String) : String;

var

Z: boolean;

begin

Z := false;

repeat

if pos(' ', S) <> 0 then Delete (S, pos (' ', S) , 1) else Z := true;

Until Z;

Uplot := S;

end;

 

begin

Write ('Введите имя исходного файла:');

Readln(s1);

Write('введите имя файла с результатом:');

Readln(s2);

Assign(f1, s1);

Assign(f2, s2) ;

{$i-}

Reset(f1);

if lOResult <> 0 then

begin

Writeln('Произошла ошибка, файл ', s1, ' не существует');

Halt ;

end;

{$i+}

Rewrite(f2);

While not Eof(f1) do

begin

Readln(f1, S);

Writeln(f2, Uplot(S));

end;

Close(f1) ;

Close(f2) ;

end.

 

Задача. Даны два текстовых файла. Вывести на экран количество строк в первом и во втором файлах. Если количество строк одинаковое, то вывести на экран те строки второго файла, которые отличаются от соответствующих строк первого.

program p12_17;

const

Namel = 'file1.txt';

Name2= 'file2.txt';

var

f1, f2 : Text;

L, K : Integer;

S1, S2 : String;

begin

Assign(f1, Namel);

Assign(f2, Name2);

{$i-}

Reset(f1) ;

Reset(f2) ;

if IQResult <> 0 then

begin

Writeln('Ошибка при открытии файлов');

Halt;

end;

{ находим количество строк в первом файле }

L:= 0;

While not Eof(f1) do

begin

Readln(f1);

inc(L);

end;

{ находим количество строк во втором файле }

К := 0;

While not Eof(f2) do

begin

Readln(f2);

inc(K);

end;

Close (f1) ;

Close (f2) ;

Reset (f1) ;

Reset (f2) ;

if К <> L then

begin

Writeln('файл ', namel, ' - ', L, ' строк' );

Writeln('файл ', namе2, ' - ', К, ' строк’ );

end

else

begin

K:= 0;

While not Eof(fl) do

begin

Readln(f1, S1) ;

Readln(f2, S2);

Inc(K);

if S1 <> S2 then

begin

Writeln(' (' , K, '): ' , S1) ;

Writeln(' (', K, ') : ' , S2) ;

end;

end;

end;

Close (f1) ;

Close (f2);

end.

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

 

Append( f );

 

Здесь f - файловая переменная типа Text. Процедура Append открывает текстовый файл для дозаписи. Если файл с именем, указанным в Assign, не существует, то вызов процедуры Append приведет к ошибке.

Пример:

program p12_18;

{ Программа дописывает в текстовый файл с матрицей новую

матрицу - результат транспонирования первой }

Const

n = 3;

m = 4;

var

Т: array[1.. n, 1 .. m] of real;

ТТ: array[1.. m, 1 .. n] of real;

f : Text;

s : String;

i, j : integer;

begin

Write('введите имя файла:');

Readln(s);

Assign(f, s);

{$i-}

Reset (f) ;

if IOResult <> 0 then

begin

Writeln('Ошибка при открытии файла');

Halt;

end;

for i : = 1 to n do

for j := 1 to m do

begin

Read(f, T[i, j] );

TT[j, i] := T[i, j] ;

end;

Close (f); { закрываем файл и повторно открываем его для записи

в конец файла }

Append ( f ) ;

{ выводим в файл пустую строку разделитель матриц }

Writeln( f ) ;

for i := 1 to m do

begin { выводим матрицу }

for j := 1 to n do

Write (f , TT[i, j] : 8 : 3) ;

Writeln(f) ;

end;

Close (f) ;

end.

 

Полезны для работы с текстовыми файлами три стандартные логические функции (ниже f - файловая переменная):

· EOLN(f) – возвращает значение true, если в файле достигнут конец строки, false – в противном случае;

· SEEKEOLN(f) – пропускает пробелы и знаки табуляции до конца строки или до первого значащего символа и возвращает значение true, если достигнут конец строки, false – в противном случае;

· SEEKEOF(f) – пропускает все пробелы, знаки табуляции и маркеры конца строки до конца файла или до первого значащего символа и возвращает значение true, если достигнут конец файла, false – в противном случае.