Файлы. Общая концепция организации ввода-вывода данных в С++. Средства класса ios, обеспечивающие точную настройку вывода, страница 13

Рассмотрим короткий текстовый файл (цифры в квадратных скобках – управляющие коды с тем же номером, в текстовом файле они занимают по одному символу и в текстовых режимах, как правило, на экран не выводятся, хотя и управляют выводом):

[13][10]

Вы читаете текстовый файл, который [13][10]

может храниться на диске или выводиться на экран.[13][10]

В нем можно хранить цифровые записи чисел:[13][10]

123         456      789      0[13][10]

234         567      890      1[13][10]

1.2          3.4       5.60     4[13][10]

-100.254[13][10]

Конец файла[13][10]

[26]

Заметьте, что каждая строка заканчивается признаком конца строки, даже пустая (1-ая сверху). Самый последний символ в файле – признак его конца. Реально файл хранится как сплошная последовательность символов и разбивается на строки лишь при его выводе на экран. Пустой текстовый файл содержит один символ EOF.

Текстовый файл является файлом последовательного доступа, т.е. любой элемент файла может быть прочитан или записан, только если перед ним был прочитан или записан элемент файла, непосредственно ему предшествующий. В данном случае последовательностью чтения или записи можно управлять только косвенно. Например, чтобы прочитать из файла пятый элемент (пятую строку, например), необходимо считать «впустую» четыре первых значения.

В каждый момент времени позиции в файле, откуда выполняется чтение и куда производится запись, определяются значениями указателей позиций записи и чтения файла. Позиционирование указателей записи и чтения (т.е. установка на нужные байты) выполняется либо автоматически, либо за счет явного управления их положением. В стандартной библиотеке ввода-вывода С++ имеются соответствующие средства.

Данные, которые формируются и записываются в файл последовательного доступа, не могут быть модифицированы без риска разрушения других данных в файле. Например, вполне возможно, что некоторое данное, перезаписываемое на место старого, будет иметь несколько лишних символов, и это, несомненно, испортит старые данные.

Текстовые файлы являются форматируемыми. Обычно операции обмена с текстовым файлом сопровождаются преобразованием информации  аналогично тому, как это происходит для стандартных потоков. В модели форматированного ввода-вывода, используемой операциями поместить в поток  << и извлечь из потока >>,  режимы форматирования установлены по умолчанию.

Целые и вещественные значения в текстовом файле имеют внешнее (текстовое) представление и отделяются друг от друга пробельным символом (чтобы узнать, где кончается одно число и начинается другое, при выводе в файл их надо их разделять пробельными символами). При чтении чисел из файла, они автоматически преобразуются из текстового представления во внутреннее, машинное.

При выводе чисел в текстовый файл, они преобразуются из внутреннего представления в символьный (текстовый) вид. При этом поля данных могут быть различных размеров: количество записываемых по умолчанию символов зависит от величины числа. Например, 5, 11, -111, 25385 – целые числа типа int, в машинном представлении хранятся в одинаковом количестве байтов, но при форматированном выводе этих чисел в текстовый файл на диске (или на экран), они занимают поля разных размеров (соответственно, 1, 2, 4, 5 символов). Именно поэтому модель форматированного ввода-вывода обычно не применима для обновления данных на месте.

Такое обновление может быть реализовано косвенно. Например, все данные до изменяемого значения можно скопировать в новый файл последовательного доступа, затем записать туда новое измененное значение, а после него – скопировать оставшуюся часть старого файла.

Форматирование не выполняется только в том случае, если содержимое текстового файла обрабатывается как символы или строки.

Форматированием можно управлять явным образом, не полагаясь на умолчания. Для этого, как мы уже знаем, имеются специальные средства форматирования (флаги, методы, манипуляторы). Они позволяют форматировать стандартные и строковые потоки, а также потоки, связанные с текстовыми файлами, и применяются во всех случаях совершенно одинаково.