Лекция
Тема:
«Текстовые файлы в программах на 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);
end.