Лекция

Тема: «Текстовые файлы в программах на Turbo Pascal»

 

План

1. Основные понятия

2. Методы для работы с файлами

3. Примеры решения задачи с текстовыми файлами

 

1. Основные понятия

Текстовые файлы предназначены для хранения текстовой информации. Именно в таких файлах хранятся, например, исходные тексты программ. Текстовые файлы могут состоять из элементов символьного (char) и строкового (string) типа данных. Ключевое слово Text указывает, что файловая переменная создается для работы с текстовым файлом:

 

Var <идентификатор>: Text;

 

Возможные расширения текстовых файлов:

*.txt, *.log, *.htm, *.html

 

При создании текстового файла каждая строка завершается специальной комбинацией, называемой «конец строки». Комбинация «конец строки» состоит из двух символов: перевод каретки (ASCII-код #13) и перевод строки (#10). Завершается текстовый файл символом конец файла (#26).

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

Предусмотрены два режима работы: режим для записи в файл информации и для чтения ее из файла. Одновременная запись и чтение запрещены.

 

2. Методы для работы с файлами

Связывание файла с местом на диске

Assign(имя файловой переменной, ‘путь к файлу’)

Процедура Assign связывает переменную файлового типа с физическим файлом. Например, установить соответствие между переменной F и текстовым файлом file1.txt, расположенном на диске D, можно так:

Assign(F, ‘D:\file1.txt’)

 

Если путь файла задать только именем файла и расширением, он будет храниться в том же каталоге, что и файл программы. Например, программа сохранена в папке C:\DOS\Tp7_Win7\prg, то при записи вида

Assign(F, ‘file1.txt’);

указываем, что файл с именем file1.txt находится в папке с программой, т.е. C:\DOS\Tp7_Win7\prg.

 

Создание файла

Процедура открытия создаваемого файла для записи в него информации; если файл с таким именем уже существует, то информация в нем стирается:

Rewrite (f);

 

Открытие файла

Процедура открытия существующего файла для чтения при последовательном доступе:

Reset (f);

После открытия файла для чтения оператором Read или Readln можно осуществить последовательное считывание элементов в программу.

При открытии курсор устанавливается в начало файла.

Описание: открытие файла

 

Добавление в конец файла

Append (f);

 

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

Процедура Append открывает существующий внешний файл с именем, определенным в файловой переменной F. Если внешний файл с данным именем не существует, то происходит ошибка ввода/вывода. Если F уже открыт, то он закрывается и вновь открывается. Текущая позиция файла устанавливается на конец файла.

Добавим в конец некоторого файла file1.txt строку str. Считаем, что файл file1.txt существует и в нем есть некоторая информация, также строка str содержит текст.

 

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

Assign(F, ‘file1.txt’);

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

Append(F);

{записываем в файл F строку str}

Write(F, str);

{закрываем файл}

Close(F);

 

Чтение из файла

Read (f, список переменных);

ReadLn (f, список переменных);

Отличие ReadLn от Read в том, что при использовании Readln после прочтения данных пропускаются все оставшиеся символы в данной строке, включая метку конца строки.

·       чтение осуществляется с той позиции, где в данный момент стоит курсор;

·       после чтения курсор сдвигается к первому непрочитанному символу.

 

Описание: чтение из файла

 

Описание: Чтение до конца строки

 

Запись в текстовый файл

Write (f, список переменных);

WriteLn (f, список переменных);

 

где f — файловая переменная, а второй параметр – выводимые из программы и вводимые в файл данные (в виде значений переменных или просто данные).

 

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

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

·       текстовые файлы удобнее для восприятия человеком, а типизированные соответствуют машинному представлению объектов;

·       текстовые файлы, как правило, длиннее типизированных;

·       длина текстовых файлов зависит не только от количества записей, но и от величины переменных.

Так, в типизированном файле числа 6, 65 и 165 как целые будут представлены одним и тем же числом байт. А в текстовых файлах, после преобразования в строку, они будут иметь разную длину. Это вызывает проблемы при расшифровке текстовых файлов. Пусть в текстовый файл пишутся подряд целые числа (типа byte): 2, 12, 2, 128. Тогда в файле образуется запись 2122128. При попытке прочитать из такого файла переменную типа byte программа прочитает всю строку и выдаст сообщение об ошибке, связанной с переполнением диапазона (так как переменная типа byte не может поместить в себе число 2122128).

Такой файл не понятен не только машине, но и человеку.

Чтобы избежать этой ошибки, достаточно вставить при записи в файл после каждой переменной пробел. Тогда программа при каждом чтении берет символы от пробела до пробела и правильно преобразует текстовое представление в число.

Кроме процедур read и write при работе с текстовыми файлами используются их разновидности readln и writeln. Отличие заключается в том, что процедура writeln после записи заданного списка записывает в файл специальный маркер конца строки. Этот признак воспринимается как переход к новой строке. Процедура readln после считывания заданного списка ищет в файле следующий признак конца строки и подготавливается к чтению с начала следующей строки.

 

Нахождение конца файла:

Eof (f);

Логическая функция, возвращающая True, если достигнут конец файла.

 

Нахождение конца строки:

Eoln (f);

Логическая функция, возвращающая True, если достигнут конец строки.

 

Удаление файла

Erase (переменная_файла);

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

 

Переименование файла

Rename (переменная_файла,'новое имя файла');

 

Параметр «переменная_файла» представляет собой файловую переменную, соответствующую любому файлу любого типа. Параметр «новое имя файла» является выражением строкового типа. Внешнему файлу, связанному с файловой переменной, присваивается новое имя. Дальнейшие операции с файловой переменной будут выполняться с внешним файлом с новым именем.

 

Закрытие:

Close (f);

Процедура Close сбрасывает буфер файла f и закрывает файл f. После вызова Close данные больше не могут быть прочитаны или записаны в f. Чтобы снова открыть файл, закрытый процедурой Close, не нужно снова связывать файловую переменную с файлом. Достаточно вызова одной из подпрограмм Reset или Rewrite.

 

Вывод: Таким образом, работа с файлом осуществляется через три основных шага:

- процедура assign.

- процедура reset или rewrite.

- процедура close.

 

3. Примеры решения задач с текстовыми файлами

Пример 1. Необходимо сформировать текстовый файл, затем переписать из данного файла во второй только те строки, которые начинаются с буквы «А» или «а». Имя второго файла (например, name.txt) вводит пользователь с клавиатуры

Указания: понадобятся две файловые переменные f1 и f2, поскольку оба файла текстовые, то тип переменных будет text. Задача разбивается на три этапа: первый – формирование первого файла; второй – чтение первого файла и формирование второго; третий (проверка второго этапа) – вывод на экран содержимого второго файла.

 

uses crt;

{описание файловых переменных}

var f1,f2:text;

i,n:integer;

s,filename:string;

Begin

{Этап первый}

{формируем первый файл}

{устанавливаем связь файловой переменной с физическим файлом на диске}
    Assign(f1, 'file1.txt');

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

    Rewrite(f1); 

    {определяем количество вводимых строк}

    Writeln('Введите количество строк');

    Readln(n)

    Writeln('Введите строки');

    For i:=1 to n do
    begin
        readln(s); {вводим с клавиатуры строки}
        writeln(f1,s); {записываем последовательно строки в файл}
    end;
    Close(f1); {заканчиваем работу с первым файлом, теперь на диске существует файл с именем file1.txt, содержащий введенные нами строки}
 

{Этап второй: чтение из первого файла и формирование второго}

Writeln('Введите новое название файла');

Readln(filename);

{устанавливаем связь второй файловой переменной с физическим файлом на диске}

    Assign(f2,filename);

    Reset(f1); {открываем первый файл для чтения}
    Rewrite(f2); {открываем второй файл для записи}
{Последовательно считываем строки из первого файла, проверяем выполнение условия и записываем нужные строки во второй файл}

 

{Для чтения из текстового файла используем цикл по условию «пока не достигнут конец файла»}
    While not eof(f1) do
    Begin
        Readln(f1,s); {считываем очередную строку из первого файла}

   {если первым символом строки является символ 'A' или 'a'}
        If (s[1]='A') or (s[1]='a') then
        Writeln(f2,s); {записываем во второй файл строки, удовлетворяющие условию}
    End;

    {заканчиваем работу с файлами}
    Close(f1);

    Close(f2)
    {Этап третий: выводим на экран второй файл}
    Writeln;
    Writeln('Второй файл содержит строки:');
    Reset(f2); {открываем второй файл для чтения}
    While not eof(f2) do {пока не достигнут конец второго файла}
    Begin
        Readln(f2,s); {считываем очередную строку из второго файла}
        Writeln(s); {выводим строку на экран}
    End;
End.

 

Пример 2. Дан текстовый файл. Вывести количество содержащихся в нем символов и строк.

 

{Вывести количество символов и строк в файле}

uses crt;

var f1:text;

i,n,k1,k2:integer;

s:char;

begin

clrscr;

{считаем, что файл существует}

{устанавливаем связь файловой переменной с физическим файлом на диске}

assign(f1, '2.txt');

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

reset(f1);

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

K1:=0;

{задаем начальное значение для количества символов файла}

K2:=0;

{пока не достигнут конец файла}

while not eof(f1) do

begin

     {пока не наступит конец строки}

     while not eoln(f1) do

     begin

        {считываем из файла очередной символ в переменную s}

        read(f1,s);

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

        INC(K2);

     end;

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

 

     inc(k1);

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

     readln(f1);

end;

{закрываем файл}

close(f1);

{выводим результаты}

writeln('Количество символов: ', k2);

writeln('Количество строк: ', k1);

readln;

end.

 

Пример 3. Заполнить файл 1.txt случайными числами, числа записать в столбик. Считать из файла 1.txt числа. Затем записать их произведение в файл rez.txt.

{посчитать произведение чисел, записанных в столбик

результат записать в новый файл}

uses crt;

var f1,f2:text;

i,n,c:integer;

p:longint;

begin

clrscr;

{Этап 1: создаем первый файл. Каждое число запишем с новой строки}

{устанавливаем связь файловой переменной f1 с физическим файлом на диске}

assign(f1, '1.txt');

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

rewrite(f1);

writeln('Введите количество чисел');

readln(n);

randomize;

{в цикле генерируем случайные числа и записываем их в файл.

Каждое число записывается на новой строке}

for i:=1 to n do

     writeln(f1, random(50) );

{закрываем файл}

close(f1);

{Этап 2: выводим содержимое первого файла 1.txt и считаем произведение чисел}

writeln('Содержимое первого файла:');

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

reset(f1);

{задаем произведению начальное значение}

p:=1;

{пока не достигнут конец файла}

while not eof(f1) do

begin

    {считываем из файла очередное число в переменную c}

    readln(f1,c);

    {вычисляем произведение}

    p:=p*c;

    {выводим значение c на экран – для проверки правильности считывания данных из файла – необязательное действие}

    writeln(c);

end;

{закрываем первый файл}

close(f1);

{выводим значение произведения - для проверки правильности вычислений}

writeln('Произведение= ', p);

{Этап 3: записываем в файл rez.txt полученное произведение}

{устанавливаем связь файловой переменной f2 с физическим файлом на диске}

assign(f2,'rez.txt');

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

rewrite(f2);

{записываем в файл f2 текст 'Product= ' и значение переменной p}

write(f2,'Product= ',p);

{завершаем работу с файлом, закрываем его}

close(f2);

readln;

end.