- •Ввод-вывод в языке с
- •Потоковые функции
- •Открытие файлов и потоков
- •Переадресация ввода-вывода
- •Изменение буфера потока
- •Форматный вывод данных
- •Функция printf()
- •Поиск в файлах с помощью функций fseek( ), ftell( ) и rewind()
- •Синхронный и асинхронный ввод/вывод
- •3. Позиционирование указателя файла.
- •6. Запись данных в файл
- •Блокировка и разблокировка файла
- •Асинхронный режим чтения и записи файлов
- •Стандартные потоки cin, coutи cerr
- •Флаги и функции форматирования
- •Файловый ввод-вывод
- •Флаг Назначение
- •Файловый ввод
- •Файловый вывод
- •Вот результаты работы программы:
- •Двоичные файлы
- •Буферы потоков
Файловый вывод
Основные функции управления потоковым выводом сосредоточены в классе ostream. С каждым из объектов этого класса и его производных связан объект класса streambuf. Эти классы работают в связке: первый осуществляет форматирование, а второй управляет низкоуровневым буферизованным выводом. Функции класса ostream, доступные его потомкам, перечислены в табл. 9.
Таблица 9. Функции класса ostream |
|
Функция |
Описание |
opfx |
Вызывается перед каждой операцией записи для проверки наличия ошибок в потоке |
оsfx |
Вызывается после каждой операции записи для очистки буфера |
put |
Записывает в поток одиночный байт |
write |
Записывает в поток требуемое число байтов |
flush |
Очищает буфер потока; аналогичное действие выполняет манипулятор flush |
seekp |
Перемещает маркер, обозначающий текущую позицию записи, на требуемую позицию в потоке |
tellp |
Возвращает позицию маркера записи |
Класс ofstream является потомком класса ostream, ориентированным на запись данных в файлы. Его конструктор автоматически создает объект класса filebuf, управляющий низкоуровневой работой с файлом, включая поддержку буфера записи. Класс ofstream содержит такой же набор функций, что и класс ifstream(см. табл. 8).
В следующей программе в файл дважды записывается одна и та же строка — посимвольно и вся целиком.
// // ofstream. cpp // В этой программе на языке C++ демонстрируется // использование класса ofstreamдля записи данных в // файл, открытый в текстовом режиме.
#include <fstream >
#include <string.h>
#define iSTRING_MAX 40
void main (void) {
int i = 0;
char pszString [iSTRING_MAX] = "Записываемая строка\n";
// файл по умолчанию открывается в текстовом режиме ofstream ofMyOutputStream("OFSTREAM.OUT") ;
// строка выводится символ за символом; // обратите внимание, что символ '\n' . // преобразуется в два символа while (pszString[i] != '\0'){
ofMyOutputStream.put (pszString[i] ) ; cout<<”\nПозиция маркера записи: “ << ofMyOutputStream.tellp() ;
i++; }
// запись всей строки целиком
ofMyOutputStream.write(pszString, strlen(pszString)); cout<< "\nНовая позиция маркера записи: " << ofMyOutputStream.tellp();
ofMyOutputStream.close() ;}
Вот результаты работы программы:
Позиция маркера записи: 1
Позиция маркера записи: 2
Позиция маркера записи: 3
Позиция маркера записи: 18
Позиция маркера записи: 19
Позиция маркера записи: 21
Новая позиция маркера записи: 42
Цикл while последовательно, символ за символом, с помощью функции put() записывает содержимое строки pszstring в выходной поток. После вывода каждого символа Вызывается функция tellp(), возвращающая текущую позицию маркера записи. Результатам работы этой функции следует уделить немного внимания.
Строка pszString содержит 20 символов плюс концевой нулевой символ (\0), итого — 21. На хотя, если судить по выводимой информации, в поток записывается 21 символ, последним из них будет не \0. Его вообще не окажется в файле. Дело в том, что при выводе данных в файл, открытый в текстовом режиме, автоматически выполняется преобразование \n = CR/LF, т.е. символ новой строки преобразуется в пару символов возврата каретки и перевода строки. (При чтении происходит обратное преобразование.) Именно поэтому наблюдается "скачок" счетчика: после 19 идет 21. Функция put(), записывающая в файл символ \n, на самом деле помещает в файл два других символа.
Функция write() выполняет такое же преобразование, поэтому конечное значение счетчика равно 42, а не 41.