И, наконец, ввод строк. Начало строки идет сразу за последним введенным до этого символом (с первой позиции, если соответствующая строчная переменная стоит первой в списке ввода). Считывается количество символов, равное объявленной длине строки. Но если во время считывания попался символ #13, то чтение строки прекращается. Сам символ #13 (конец строки) служит разделителем строк и в переменную никогда не считывается.
Рассмотрим пример комплексного списка ввода:
Read( realVar, intVar, Ch, String11, String88).
При вводе последовательность символов будет разбита на разнотипные части следующим образом ([#13] обозначает один символ с кодом 13):
Обратите внимание, что символьная переменная Ch здесь может заполучить себе только пробел (или #13 и #9), иначе, если следом сразу начнется строка, произойдет сбой при чтении целого значения! Строка StringSS будет заполнена не целиком, а на ту часть, которая успела считаться до символа #13 (нажатия клавиши ввода или конца строки в файле).
Понятно, что лучшим способом избежать заложенных во вводе текстовой информации подвохов будет отказ от смешанных списков ввода, по крайней мере при чтении с клавиатуры.
- 241 -
Спецификация формата ввода чисел как таковая отсутствует, и единственное требование состоит в том, чтобы написание числовых значений соответствовало типам переменных в списке ввода.
При вводе с клавиатуры («с экрана») особой разницы между Read и ReadLn нет. Процедура ReadLn (Read Line) считывает значения в текущей строке и переводит позицию на начало следующей строки, даже если в текущей строке остались непрочитанные данные. Так, при чтении в текстовом файле f строки:
12.3 13.4 14.5 15.6
оператором ReadLn( f, r1, r2) вещественные переменные r1 и r2 получат значения 12.3 и 13.4, после чего произойдет переход на другую строку, и следующие два числа (14.5 и 15.6) будут проигнорированы. Вызов ReadLn ( f ) вообще пропустит строку в файле f. Вызов ReadLn без указания файла сделает паузу до нажатия клавиши ввода.
Символ-признак конца текста #26 также является разделителем и ограничивает строку, но за ним чтение уже невозможно. Файл на нем кончается! Конец файла может быть считан в символьную переменную, в строчную он не войдет (как не входит символ #13), а чтение #26 вместо ожидаемых числовых значений эквивалентно прочтению 0.
12.6.2.2. Операторы Write/WriteLn. Операторы Write и WriteLn выводят значение X или список значений X1, Х2,..., Хn в текстовый файл f. Если файл не указан, то считается, что вывод направлен в файл Output (на дисплей). Значения, как и при вводе, могут иметь лишь целые, вещественные, символьные и строковые типы, а также производные от них. Всевозможные структуры (записи, массивы) должны выводится по их полям или элементам. Множества, указатели (Pointer), файловые переменные также не могут быть выведены без предварительного их преобразования в выводимые составляющие. Исключение составляет лишь тип Boolean:
CONST
tr : Boolean = True;
fa : Boolean = False;
...
Write( tr, ' ... ' , fa );
Оператор Write напечатает на экране: 'TRUE ... FALSE'. Предостерегаем от попыток прочитать эти значения из файла в том же виде. Из этого ничего не выйдет. Чтобы получить из файла логическое значение, закодируйте его байтом:
0 = False
1 = True
- 242 -
и считайте в байтовую переменную, а затем преобразуйте в логическое значение:
VAR
by : Byte; { байтовое значение }
boo : Boolean absolute by; { логическое значение }
...
Read( by ); { вводится значение-байт 0 или 1 }
if boo then ... ; {и считается логическим значением }
Вернемся, однако, к выводу данных. Процедура Write выводит данные в текущую строку и не закрывает ее, т.е. следующие данные запишутся в ту же строку. Формально во внешнем файле размер строки не ограничен. Исключение составляет вывод на дисплей. Если выводимый текст «уперся» в правую границу окна экрана, то он на этом месте разрывается и продолжается с начала следующей строки. Кроме того, вывод символа в нижний правый угол окна автоматически сдвинет изображение вверх на строку, т.е. все-таки совершит переход на следующую строку.
Процедура WriteLn (Write Line) выводит именно строку данных и закрывает ее: приписывает символ #13 в ее конец (точнее, символы #13 и #10, но последний как бы «сливается» с основным кодом). Это автоматически открывает следующую строку, а на экране возвращает курсор в крайнюю левую позицию и опускает его на строку вниз.
Оператор WriteLn или WriteLn( f ), где f — имя логического файла, данный без списка вывода, создает пустую строку, содержащую один только признак конца.
Список вывода Write и WriteLn может содержать константы, переменные, выражения, вызовы функций — лишь бы они имели соответствующие типы и были разделены запятыми:
Write( RealVar, ' номер ', intVar, #10#10'сумма=' );
WriteLn( RealVar+IntVar, '+', Cos(5*5) );