|
Программирование >> Процедурные приложения
После окончания вывода всего файла он закрывается командой close(). Файловый вывод Основные функции управления потоковым выводом сосредоточены в классе ostream. С каждым из объектов этого класса и его производных связан объект класса streambuf. Эти классы работают в связке: первый осуществляет форматирование, а второй управляет низкоуровневым буферизованным выводом. Функции класса ostream, доступные его потомкам, перечислены в табл. 15.4.
Класс 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).
|
© 2006 - 2024 pmbk.ru. Генерация страницы: 0
При копировании материалов приветствуются ссылки. |