|
По первому тесту выполнил дважды задания. Результат получается правильный (проверял калькулятором). Пишет, что "Задание не проверено" и предлагает повторить. |
Обработка файлов средствами Free Pascal
7.4 Обработка текстовых файлов в языке Free Pascal
При работе с текстовыми файлами следует учесть следующее:
- Действие процедур reset, rewrite, close, rename, erase и функции eof аналогично их действию при работе с компонентными (типизированными) файлами.
- Процедуры seek, trunсate и функция filepos не работают с текстовыми файлами.
- Можно пользоваться процедурой открытия текстового файла append(f), где f — имя файловой переменной. Эта процедура служит для открытия файла в режиме дозаписи в конец файла. Она применима только к уже физически существующим файлам, открывает и готовит их для добавления информации в конец файла.
- Запись и чтение в текстовый файл осуществляются с помощью процедур write, writeln, read, readln следующей структуры:
read ( f, x1, x2, x3,..., xn );
read ( f, x );
readln ( f, x1, x2, x3,..., xn );
readln ( f, x );
write ( f, x1, x2, x3,..., xn );
write ( f, x );
writeln ( f, x1, x2, x3,..., xn );
writeln ( f, x );
В этих операторах f — файловая переменная. В операторах чтения (read, readln) x, x1, x2, x3,..., xn — переменные, в которые происходит чтение из файла. В операторах записи write, writeln x, x1, x2, x3,..., xn — переменные или константы, информация из которых записывается в файл.
Есть ряд особенностей при работе операторов write, writeln, read, readln с текстовыми файлами. Имена переменных могут быть целого, вещественного, символьного и строкового типа. Перед записью данных в текстовый файл с помощью процедуры write происходит их преобразование в тип string. Действие оператора writeln отличается тем, что после указанных переменных и констант в файл записывается символ "конец строки".
При чтении данных из текстового файла с помощью процедур read, readln происходит преобразование из строкового типа к нужному типу данных. Если преобразование невозможно, то генерируется код ошибки, значение которого можно узнать, обратившись к функции IOResult. Компилятор Free Pascal позволяет генерировать код программы в двух режимах: с проверкой корректности ввода-вывода и без неё.
В программу может быть включен ключ режима компиляции. Кроме того, предусмотрен перевод контроля ошибок ввода-вывода из одного состояния в другое:
- {$I+} — режим проверки ошибок ввода-вывода включён;
- {$I-} — режим проверки ошибок ввода-вывода отключён.
По умолчанию, как правило, действует режим {$I+}. Можно многократно включать и выключать режимы, создавая области с контролем ввода и без него. Все ключи компиляции описаны в приложении.
При включённом режиме проверки любая ошибка ввода-вывода будет фатальной, программа прервётся, выдав номер ошибки.
Если убрать режим проверки, то при возникновении ошибки ввода-вывода программа не будет останавливаться, а продолжит работу со следующего оператора. Результат операции ввода-вывода будет неопределён.
Для опроса кода ошибки лучше пользоваться специальной функцией IOResult, но необходимо помнить, что опросить её можно только один раз после каждой операции ввода или вывода: она обнуляет своё значение при каждом вызове. IOResult возвращает целое число, соответствующее коду последней ошибки ввода-вывода. Если IOResult=0, то при вводе-выводе ошибок не было, иначе IOResult возвращает код ошибки. Некоторые коды ошибок приведены в табл. 7.9.
| Код ошибки | Описание |
|---|---|
| 2 | файл не найден |
| 3 | путь не найден |
| 4 | слишком много открытых файлов |
| 5 | отказано в доступе |
| 12 | неверный режим доступа |
| 15 | неправильный номер диска |
| 16 | нельзя удалять текущую директорию |
| 100 | ошибка при чтении с диска |
| 101 | ошибка при записи на диск |
| 102 | не применена процедура AssignFile |
| 103 | файл не открыт |
| 104 | файл не открыт для ввода |
| 105 | файл не открыт для вывода |
| 106 | неверный номер |
| 150 | диск защищён от записи |
Рассмотрим несколько практических примеров обработки ошибок ввода-вывода:
- При открытии проверить, существует ли заданный файл и возможно ли чтение данных из него.
assign ( f, ’ abc. dat ’ ); {$I-} reset ( f ); {$I+} if IOResult<>0 then writeln ( ’файл не найден или не читается ’ ) else begin read ( f,... ); close ( f ); end; - Проверить, является ли вводимое с клавиатуры число целым.
var i : integer; begin {$I-} repeat write ( ’введите целое число i ’ ); readln ( i ); until ( IOResult =0); {$I+} {Этот цикл повторяется до тех пор, пока не будет введено целое число.} end.
При работе с текстовым файлом необходимо помнить специальные правила чтения значений переменных:
- Когда вводятся числовые значения, два числа считаются разделёнными, если между ними есть хотя бы один пробел, или символ табуляции, или символ конца строки.
- При вводе строк начало текущей строки идёт сразу за последним, введённым до этого символом. Вводится количество символов, равное объявленной длине строки. Если при чтении встретился символ "конец строки", то работа с этой строкой заканчивается. Сам символ конца строки является разделителем и в переменную никогда не считывается.
- Процедура readln считывает значения текущей строки файла, курсор переводится в новую строку файла, и дальнейший ввод осуществляется с неё.
В качестве примера работы с текстовыми файлами рассмотрим следующую задачу.
и
и их размеры. Найти матрицу
, которую дописать в файл abc.txt.Сначала создадим текстовый файл abc.txt следующей структуры: в первой строке через пробел хранятся размеры матрицы (числа N и M), затем построчно хранятся матрицы A и B.
На рис. 7.14 приведён пример файла abc.txt, в котором хранятся матрицы A(4,5) и B(4,5).
Текст консольного приложения решения задачи 7.8 с комментариями приведён ниже.
program Project1;
{$mode objfpc}{$H+}
uses
Classes, SysUtils
{ you can add units after this };
var
f : Text;
i, j, N,M: word;
a, b, c : array [ 1.. 1000, 1.. 1000 ] of real;
begin
//Связываем файловую переменную f с файлом на диске.
AssignFile ( f, ’ abc. t x t ’ );
//Открываем файл в режиме чтения.
Reset ( f );
//Считываем из первой строки файла abc.txt значения N и M.
Read( f,N,M);
//Последовательно считываем элементы матрицы А из файла.
for i :=1 to N do
for j :=1 to M do
read ( f, a [ i, j ] );
//Последовательно считываем элементы матрицы B из файла.
for i :=1 to N do
for j :=1 to M do
read ( f, b [ i, j ] );
//Формируем матрицу C=A+B.
for i :=1 to N do
for j :=1 to M do
c [ i, j ] : = a [ i, j ]+b [ i ] [ j ];
//Закрываем файл f.
CloseFile ( f );
//Открываем файл в режиме дозаписи.
Append( f );
//Дозапись матрицы C в файл.
for i :=1 to N do
begin
for j :=1 to M do
//Дописываем в файл очередной элемент матрицы и пробел в
//текстовый файл.
write ( f, c [ i, j ] : 1 : 2, ’ ’ );
//По окончании вывода строки матрицы переходим на новую
//строку в текстовом файле.
writeln ( f );
end;
//Закрываем файл.
CloseFile ( f );
end.
После работы программы файл abc.txt будет примерно таким, как показано на рис. 7.15.

