|
Программирование >> Операторы преобразования типа
Функция rdbufO позволяет нескольким объектам потоков данных читать из одного входного канала или записывать в один выходной канал без нарушения порядка ввода-вывода. Однако использование нескольких потоковых буферов создает проблемы из-за буферизации операций ввода-вывода. Следовательно, применение для одного канала ввода-вывода разных потоков данных с разными буферами чревато ошибками при передаче данных. У классов basicjstream и baslc ostream имеются дополнительные конструкторы для инициализации потока данных с переданным в качестве аргумента буфером. Пример: io/rdbufl.cpp finclude <lostreain> finclude <fstrGa[n> using namespace std: int mainO { Поток для шестнадцатеричного стандартного вывода ostream hexoutCcout.rdbufO): hexout.setf (ios::hex, los::basefie1d); hexout.setf (ios::showbasG): Переключение между десятичным и шестнадцатеричным выводом hexout hexout: 177 cout cout: 177 hexout hexout: -49 cout cout: -49 hexout Gnd1: Учтите, что деструктор классов basicjstream и baslc ostream пе удаляет соответствующий потоковый буфер (который не открывается этими классами). Следовательно, чтобы передать поток данных при вызове, вместо ссылки на поток можно передать указатель на потоковый буфер: io/rdbufZ.cpp finclude <1ostreain> finclude <fstream> void hexMultipHcationTable (std: :streambuf* buffer. 1nt num) { std;:ostream hexout(buffer); hexout std::hex std::showbase: for (int i=l: i<-num; ++1) { for (int j l: j<-10; ++j) { hexout i *j : hexout std::endl; * ) НЕ ЗАКРЫВАЕТ буфер int mainO using namespace std; int num - 5; cout We print num lines hexadecimal endl: hexMulti pii cati onTab!e(cout,rdbuf().num): cout That was the output of num hexadecimal lines endl; Преимущество такого подхода заключается в том, что после модификации формат не нужно возвращать в исходное состояние, поскольку формат относится к объекту потока данных, а не к буферу. Результат выполнения программы выглядит так: We print 5 lines hexadecimally 0x1 0x2 0x3 0x4 0x5 0x6 0x7 0x8 0x9 Oxa 0x2 0x4 0x6 0x8 Oxa Oxc Oxe 0x12 0x14 0x3 0x6 0x9 Oxc Oxf Ox 12 0x15 0x18 Oxlb Oxle 0x4 0x8 Oxc 0x10 0x14 0x18 Oxlc 0x20 0x24 0x28 0x5 Oxa Oxf 0x14 0x19 Oxle 0x23 0x28 0x2d 0x32 That was the output of 5 hexadecimal lines Впрочем, наряду с достоинствами имеется и недостаток - конструирование и уничтожение объекта потока данных обходится дороже, чем простая установка и восстановление форматных флагов. Также следует помнить, что уничтожение объекта потока данных не приводит к очистке буфера. Очищать выходной буфер необходимо вручную -. Замечание о том, что потоковый буфер не уничтожается, относится только к классам basicjstream и basic ostream. Другие потоковые классы уничтожают буферы, созданные ими же, но оставляют буферы, назначенные функцией rdbuf() (см. далее). Перенаправление стандартных потоков данных В старых реализациях библиотеки IOStгeaш глобальные потоки данных cin, cout, сегг и clog были объектами классов istream withassign и ostream withassign. Это позволяло перенаправлять потоки данных, присваивая одни потоки другим. Этот механизм был исключен из стандартной библиотеки С++. Тем не менее сама возможность перенаправления потоков данных была сохранена и расширена так, что теперь она может применятьсяко всем потокам данных. Перенаправление потока данных осуществляется назначением потокового буфера. В механизме назначения потоковых буферов перенаправление потоков данных находится под управлением программы, операционная система здесь не участвует. Например, в результате выполнения следующего фрагмента данные, отправленные в поток данных cout, будут передаваться не в стандартный выходной канал, а в файл cout.txt: std::ofstream file ( cout.txt ); std::cout.rdbuf (file.rdbufO); Для передачи всей форматной информации между потоками данных можно воспользоваться функцией copyfmt(): std:lofstream file ( cout.txt ); filG.copyfmt (std::cout): std::cout.rdbuf (fUe.rdbufO); ВНИМАНИЕ- Объект file является локальным и уничтожается в конце блока, что также приводит к уничтожению соответствующего потокового буфера. В этом отношении файловые потоки данных отличаются от обычных , поскольку они создают свои объекты потоковых буферов во время консфуиро-вания и уничтожают их при уничтожении. Учитывая это замечание, в приведенном примере дальнейшее использование объекта cout для записи невозможно. Более того, его даже нельзя безопасно уничтожить при завершении программы. По этой причине прежний буфер следует всегда сохранять с последующим восстановлением! В представленном ниже примере это делается в функции redirect(): 1o/redirect.cpp finclude <iostreani> finclude <fstrGain> using namespace std: void redirect(ostream&); int mainO cout the first row end1: redirect(cout); cout the last row endl; void redirect (ostream& strm) { ofstream fileCredirect.txt ): Сохранение выходного буфера потоке! streambuf* strm buffer * strm.rdbufО:
|
© 2006 - 2025 pmbk.ru. Генерация страницы: 0
При копировании материалов приветствуются ссылки. |