Текстовые файлы – самые простые. Они состоят из строк. Каждая строка заканчивается комбинацией символов с кодами 13 и 10. Ниже перечислены процедуры и функции, обеспечивающие работу с текстовыми файлами:
VAR f: TEXTFILE – особый тип данных "файловая переменная". Файловая переменная – представитель файла в программе;
ASSIGNFILE(f,name) – связывает файловую переменную f с файлом с именем name;
SetTextBuf(f,buf) – выделение буфера (массива) buf файлу f;
Reset(f) – открытие файла f для чтения;
ReWrite(f) – создание файла f;
ReadLn(f,a) – считывание строки из файла f в переменную a типа STRING;
WriteLn(f,a) – запись в файл f текстовой строки a;
EOF(f) – проверка конца файла. Если достигнут конец, возвращает TRUE;
CloseFile(f) – закрытие файла f
Рассмотрим простейший пример – вывод текстового файла на экран. Скорее всего, на компьютере есть командный файл C:\Autoexec.bat, автоматически выполняемый при перезагрузке машины. Интересно посмотреть, что там внутри…
VAR f:TEXTFILE; a:STRING; p:^BYTE;
BEGIN
GetMem(p,10240); { буфер в 10Кб}
AssignFile(f,’C:\autoexec.bat’);
SetTextBuf(f,p^);
Reset(f);
WHILE Not(EOF(f)) DO
BEGIN
ReadLn(f,a);
Memo1.Lines.Add(a)
END;
CloseFile(f);
FreeMem(p,10240);
Обратите внимание на то, что буфер выделяется в динамической памяти. Цикл WHILE NOT(EOF(f)) … - стандартный цикл считывания файла, пока не достигнут его конец (end-of-file). В конце программы выполняются два совершенно необходимых действия: во-первых, файл закрывается, а во-вторых, освобождается захваченная область динамической памяти.
О закрытии файлов надо сказать особо. В сове время было установлено, что очень легко научить обезьяну открывать кран с водой, но вот приучить ее закрывать за собой воду практически невозможно. Ситуация с начинающими программистами аналогична – они забывают закрывать файлы. Незакрытый файл – подлинное бедствие. Дело в том, что число одновременно открытых файлов в операционной системе ограничено, причем число это не очень большое – обычно 40. Из 40 файлов около десятка постоянно открыты самой операционной системой – остается 30. Если программа-вредитель не закрывает за собой файлы, для операционной системы они регистрируются как открытые. В итоге примерно на тридцатом запуске такой программы, а то и того раньше, компьютер зависает.
А что будет, если в текстовый файл вывести число? Например, так:
VAR a:WORD; f:TEXTFILE;
…
WriteLn(f,a);
Как ни странно, ничего страшного не произойдет. Дело в том, что для удобства пользователя процедуры Read и Write сделаны с отступлением от жесткой типизации. Их аргументами могут быть переменные многих типов, к тому же число аргументов может быть произвольным. Интересно, что такие "вольности" из серьезных языков позволяет только Паскаль, несмотря на его в целом строгую структуру. Поэтому, если в текстовый файл будет выводиться число, Паскаль автоматически преобразует его в текстовый вид. Это не столь простая задача, как кажется. В памяти числа хранятся в компактном двоичном представлении. Например, число 500 занимает два байта и выглядит как значения: 1 (старший байт) и 244 (младший байт). Число 500 получается по формуле
. Чтобы перевести число в десятичный вид, понятный человеку, выполняются следующие действия:
I:=0;
REPEAT
d[I]:=x MOD 10;
x:= x DIV 10;
INC(i);
UNTIL x=0;
REPEAT
DEC(I);
Write(f,CHR(d[I]+ORD(‘0’))
UNTIL I=0;
Операции DIV и MOD позволяют легко разделить число на десятичные цифры (в данном случае это 5,0 и 0). Основная хитрость программы заключена в строке CHR(d[I]+ORD(‘0’)). В любых таблицах кодировок коды цифр идут подряд, возрастая от 0 до 9. В данном примере берется код символа "0" {ORD('0')} и к нему прибавляется текущая цифра d[i], а полученное значение используется как код символа для получения самого символа при помощи функции CHR.