Программирование >>  Процедурные приложения 

1 ... 79 80 81 [ 82 ] 83 84 85 ... 150


После окончания вывода всего файла он закрывается командой close().

Файловый вывод

Основные функции управления потоковым выводом сосредоточены в классе ostream. С каждым из объектов этого класса и его производных связан объект класса streambuf. Эти классы работают в связке: первый осуществляет форматирование, а второй управляет низкоуровневым буферизованным выводом. Функции класса ostream, доступные его потомкам, перечислены в табл. 15.4.

[Таблица 15.4. Функции класса ostream

Описание

opfx

[Вызывается перед каждой операцией записи для проверки наличия ошибок в потоке

оsfx

Вызывается после каждой операции записи для очистки буфера

Записывает в поток одиночный байт

write

Записывает в поток требуемое число байтов

flush

Очищает буфер потока; аналогичное действие выполняет манипулятор flush

seekp

Перемещает маркер, обозначающий текущую позицию записи, на требуемую позицию в потоке

tellp

Возвращает позицию маркера записи

Класс ofstream является потомком класса ostream, ориентированным на запись данных в файлы. Его конструктор автоматически создает объект класса filebuf, управляющий низкоуровневой работой с файлом, включая поддержку буфера записи. Класс ofstream содержит такой же набор функций, что и класс ifstream(см. табл. 15.3).

В следующей программе в файл дважды записывается одна и та же строка - посимвольно и вся целиком.

ofstream. cpp

В этой программе на языке C++ демонстрируется использование класса ofstreamдля записи данных в файл, открытый в текстовом режиме. #include <fstream.h> #include <string.h> #define iSTRING MAX 4 0 void main (void) { int i = 0;

char pszString [iSTRING MAX] = Записываемая строка\n ;

файл по умолчанию открывается в текстовом режиме

ofstream ofMyOutputStream( OFSTREAM.OUT ) ;

строка выводится символ за символом;

обратите внимание, что символ \n .

преобразуется в два символа

while (pszString[i] != \0){

ofMyOutputStream.put (pszStringfi] ) ;

cout<< !\пПозиция маркера записи: << 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.

Двоичные файлы

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

binary. срр

Эта программа является модификацией пред1дущего примера

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

#include <fstream. h> #include <string.h> #define iSTRING MAX 4 0 void main (void) << int i = 0;

char pszString [iSTRING MAX] = Записываемая строка\n ; файл открывается в двоичном режиме

ofstream ofMyOutputStream( OFSTREAM.OUT , ios :: binary)

строка выводится символ за символом;

обратите внимание, что символ \n

никак не преобразуется

while (pszString [i]!= \0) {

ofMyOutputStream.put (pszString [i]);

cout << \пПозиция маркера записи: << ofMyOutputStream.tellpO ;

i++> 1

запись всей строки целиком .

ofMyOutputStream.write(pszString, strlen(pszString)), cout<< \nНовая позиция маркера записи: << ofMyOutputStream.tellp() ; ofMyOutputStream.close() ;

Вот результаты работы программы:

Позиция маркера записи: 1



Позиция

маркера

записи:

Позиция

маркера

записи:

Позиция

маркера

записи:

Позиция

маркера

записи:

Позиция

маркера

записи:

Новая позиция маркера записи: 40

При выводе строки pszString не происходит замены концевого символа \n парой символов возврата каретки и перевода строки, поэтому в поток записывается 20 символов - ровно столько, сколько содержится в строке.

Буферы потоков

В основе всех буферизованных потоков ввода-вывода в C++ лежит класс streambuf. В этом классе описаны основные операции, выполняемые над буферами ввода-вывода (табл. 15.5). Любой класс, порожденный от ios, наследует указатель на объект класса streambuf. Именно последний выполняет реальную работу по вводу и выводу данных.

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

Класс streambuf является абстрактным, т.е. создать его объект напрямую нельзя (его конструктор является защищенным и не может быть вызван из программы). В то же время, имеются три производных от него класса, предназначенные для работы с потоками конкретного типа: filebuf (буферы дисковых файлов), strstreambuf (строковые буферы, хранящиеся в памяти) и stdiobuf (буферизация дискового ввода-вывода с помощью стандартных системных функций). Кроме того, можно создавать собственные классы, порожденные от streambuf, переопределяя его виртуальные функции (табл. 15.6) и настраивая, таким образом, его работу в соответствии с потребностями конкретного приложения. Только из производных классов можно вызывать и многочисленные защищенные функции этого класса, управляющие областью резервирования (табл. 15.7).

Таблица 15.5. Открытые функции класса streambuf

Открытая функция

Описание

n avail

Возвращает число символов в области ввода

sgetc

Возвращает символ, на который ссылается указатель области ввода; при этом указатель не перемещается

snextc

Перемещает указатель области ввода на одну позицию вперед, после чего возвращает текущий символ

sbumpc

Возвращает текущий символ и затем перемещает указатель области ввода на одну позицию вперед

stossc

Перемещает указатель области ввода на одну позицию вперед, но не возвращает символ

sputbaqkc

Перемещает указатель области ввода на одну позицию назад, возвращая символ в буфер

sgetn

Читает требуемое количество символов из буфера

out waiting

Возвращает число символов в области вывода

sputc

Записывает символ в буфер и перемещает указатель области вывода на одну позицию вперед

sputn

Записывает требуемое количество символов в буфер и перемещает указатель области вывода на соответствующее число позиций

В текстовом виде записывает в стандартный выходной поток различного рода информацию о состоянии буфера

Таблица 15.6. Виртуальные функции класса streambuf

Виртуальная функция

Описание

sync

ЛОчищает области ввода и вывода

setbuf

[[Добавляет к буферу указанную зарезервированную область памяти

seekoff

[Перемещает указатель области ввода или вывода на указанное количество байтов ][относительно текущей позиции



1 ... 79 80 81 [ 82 ] 83 84 85 ... 150

© 2006 - 2024 pmbk.ru. Генерация страницы: 0
При копировании материалов приветствуются ссылки.
Яндекс.Метрика