
6.5.1. Текстовые файлы
Если текстовый файл открыт с файловым указателем типа FileText, внешний файл интерпретируется специальным образом: считается, что он представляет последовательность символов сформатированную в строки, где каждая строка заканчивается признаком конца строки (символ возврата каретки, возможно сопровождаемый символом перевода строки #13#10). Тип FileText в каком-то смысле соответствует типу file of Char.
Для текстовых файлов, есть специальные процедуры Read и Write, которые позволяют читать и записывать величины неcимвольного типа. Такие величины автоматически интерпретируются из их символьного представления. Например, Read(F,I), где I – переменная целого типа, читает последовательность цифр, интерпретирует эту последовательность как десятичное целое, и загружает это значение в переменную I.
Есть две стандартные текстфайловые переменные: Input и Output. Стандартная файловая переменная Input указывает на файл только для чтения, связываемый с операционным системным вводом (обычно клавиатурой). Стандартная файловая переменная Output указывает на файл только для записи, связываемый с операционным системным стандартным выводом (обычно дисплеем). Прежде, чем приложение начнет выполняться, файлы Input и Output автоматически открываются, как при выполнении следующих команд:
AssignFile(Input, '');
Reset(Input);
AssignFile(Output, '');
Rewrite(Output);
Примечание:
Текстовый ввод/вывод доступен только в консольных приложениях.
Некоторым стандартным процедурам I/O, работающим с текстовыми файлами, не нужно иметь файловую переменную, явно указанную как параметр. Если файловый параметр опускается, то по умолчанию принимаются Input или Output. Например, Read(X) соответствует Read(Input, X) и Write(X) соответствует Write(Output, X).
Принтер тоже может выступать как текстовый файл для записи. В этом случае вместо процедуры AssignFile(f,FileName) необходимо использовать AssignPrn. Например,
AssignPrn(f); Rewrite(f);
Writeln(f, 'Напечатана одна строка');
CloseFile(f);
Любой принтер управляется с помощью кодов символов и команд, отправляемых на принтер процедурой Write. Первые 32 кода таблицы кодов ASCII называются управляющими кодами. Так как этого количества не хватает для всех команд, то многие команды состоят из двух и более кодов. В этом случае последовательность управляющих кодов для принтера всегда начинается с кода 27. В системе ASCII для этого кода используется аббревиатура ESC, а сами команды называются ESC-последовательностями. Система команд зависит от типа принтера, но во многом эти команды совпадают. Ниже приводится система некоторых команд для принтера Epson FX-800.
Таблица 6.4. Команды для принтера Epson FX-800
Обозначения |
Код |
Назначение |
BEL |
7 |
Звуковой сигнал на 1 с. |
HT |
9 |
Переход в следующую позицию горизонтальной табуляции. Метки горизонтальной табуляции устанавливаются командой Esc D |
LF |
10 |
Печатает данные, оставшиеся в буфере и передвигает бумагу на 1 строку. Пропуск строки (1/6 дюйма=4.23 см) может быть изменен командами Esc A, Esc 0, Esc 1, Esc 2, Esc 3 |
CR |
13 |
Оканчивает строку принтера и печатает данные из буфера без перевода каретки |
SO |
14 |
Изменяет режим печати на двойную ширину |
SI |
15 |
Переводит принтер в режим уплотненной печати |
Esc - 1 |
27 45 1 |
Печать с подчеркиванием |
Esc - 0 |
27 45 0 |
Печать с подчеркиванием отменить |
Esc 0 |
27 48 |
Интервал 1/8 дюйма=3.175 мм |
Esc 1 |
27 49 |
Интервал 7/72 дюйма=2.74 мм |
Esc 2 |
27 50 |
Интервал 1/6 дюйма=4.23 мм |
Файловый указатель должен быть связан с внешним файлом процедурой AssignFile, с последующим использованием процедур Reset, Rewrite или Append. Если текстовый файл открывался с помощью Reset, то возникает ошибка при записи в файл. Также возникает ошибка при чтении текстового файла, который открывался Rewrite или Append.
Пример 1. Запись в текстовый файл двумерного массива.
Листинг 6.1.а.
var x: array[1..n,1..m] of real;
F: filetext;
i,j: integer;
begin
AssignFile(f,’f.txt’); Rewrite(f);
for j:=1 to m do begin
Write(f,j:3,’ ‘);
for i:=1 to n do Write(f,x[i,j]:8:2,’ ‘);
Writeln(f);
end;
CloseFile(f);
end;
В каждой строке записывается номер строки и n вещественных чисел. Между числами в качестве разделителя записывается пробел. После записи каждой группы чисел происходит перевод каретки оператором Writeln(f).
Запись двухмерного массива можно реализовать несколько иначе, если мы не будем в начале каждой строки указывать номер строки.
Пример 2. Запись в текстовый файл двумерного массива.
Листинг 6.1.б.
var x: array[1..n,1..m] of real;
F: filetext;
i,j: integer;
begin
AssignFile(f,’f.txt’); Rewrite(f);
for j:=1 to m do begin
for i:=1 to n do Write(f,x[i,j]:8:2,’ ‘);
Writeln(f);
end;
CloseFile(f);
end;
Пример 3. Чтение из текстового файла двумерного массива.
Листинг 6.2.а.
var x: array[1..n,1..m] of real;
f: filetext;
i,j: integer;
begin
AssignFile(f,’f.txt’); Reset(f);
i:=0;
while not EOF(f) do
begin
Read(f,j);
for i:=1 to n do Read(f,x[i,j]);
Readln(f);
end;
CloseFile(f);
end;
Если бы при записи в файл числа не были разделены пробелами, то все они склеились, и не было возможности прочитать их заново. Обратите внимание на то, что при таком способе чтения необходимо знать значение переменной n. Если же значение этой переменной до чтения неизвестно, то удобнее использовать циклы с предусловием while и функция проверки конца строки текстового файла EOLN(f):
Листинг 6.2.б.
var x: array[1..n,1..m] of real;
f: filetext;
i,j: integer;
begin
AssignFile(f,’f.txt’); Reset(f);
i:=0;
while not EOF(f) do begin
j:=0;
while not EOLN(f) do begin
j:=j+1; Read(f,x[i,j]);
end;
Readln(f);
end;
CloseFile(f);
end;