|
Программирование >> Операторы преобразования типа
Следующий пример демонстрирует использование функции seekg(). В ием определена функция, которая дважды выводит содержимое файла: Заголовочные файлы для ввода-вывода #include <iostreanp #include <fstream> void printFileTwice (const char* filename) { Открытие файла std::ifstream flle(filename): Первый вывод содержиного std::cout file.rdbufO; Возврат к началу файла file.seekg(O); Второй вывод содержиного std; :cout file.rdbufO; int main (int argc. char* argv[]) Двукратный вывод всех файлов, переданных в командной строке for Cint i=l; i<argc: ++i) { printFileTwice(argv[i]); Обратите внимание на вывод содержимого файла функцией file.rdbufO (см. с. 656). Операция выполняется прямо с потоковым буфером и не изменяет состояния потока данных. Если содержимое file выводится функциями потокового интерфейса, такими как getline() (см. с. 583), вам придется сбросить состояние файла file функцией с1еаг() перед тем, как выполнять с ним любые операции, включая изменение позиции чтения, поскольку эти функции устанавливают флаги ios::eofbit и ios::failbit при достижении конца файла. Управление позициями чтения и записи осуществляется разными функциями, но для стандартных потоков данных поддерживается общая позиция чтения/ записи в одном потоковом буфере. Это важно, если буфер используется несколькими потоками данных. За дополнительной информацией обращайтесь к с. 613. Файловые дескрипторы Некоторые реализации позволяют присоединить поток данных к ранее открьгго-му каналу ввода-вывода. Для этого файловый поток данных инициализируется файловым дескриптором. Файловый дескриптор представляет собой целое число, идентифицирующее открытый канал ввода-вывода. В системах семейства UNIX файловые дескрип- торы используются в низкоуровневом интерфейсе с функциями ввода-вывода операционной системы. Определены три стандартных файловых дескриптора: О О - стандартный канал ввода; О 1 - стандартный канал вывода; О 2 - стандартный канал вывода ошибок. Каналы могут связываться с файлами, консолью, процессами или другими средствами ввода-вывода. К сожалению, стандартная библиотека С++ не поддерживает присоединение потоков данных к каналам ввода-вывода при помощи файловых дескрипторов. Это объясняется тем, что проектировщики стремились обеспечить независимость от конкретных особенностей операционных систем. Впрочем, на практике такая возможность существует, а ее единственный недостаток - влияние на переносимость программ. На сегодняшний день в стандартах интерфейсов операционных систем (таких, как POSIX или X/OPEN) не существует такой спецификации, причем ее разработка даже не планируется. И все же поток данных можно инициализировать по файловому дескриптору. Описание и реализация возможного решения приводятся на с. 641. Связывание потоков ввода-вывода Иногда перед программистом возникает задача связывания двух потоков данных. Предположим, вы хотите, чтобы перед вводом данных на экран выводился текст с запросом на ввод. Другой пример - чтение и запись в одном потоке данных (это относится в основном к файлам). Третий характерный пример - выполнение операций с потоком данных в разных форматах. Все эти примеры будут рассмотрены далее. Нежесткое связывание функцией tie При связывании потока с выходным потоком данных их буферы синхронизируются так, что содержимое буфера выходного потока данных будет очищаться функцией flush() перед любой операцией ввода или вывода в другом потоке данных, В табл. 13.37 перечислены функции связывания потоков данных, определенные в классе basic ios. Таблица 13.37. Связывание потоков данных Функция Описание tie() Возвращает указатель на выходной поток, связанный с данным потоком tJe(ostream* strm) Связывает поток с входным потоком, заданным аргументом, и возвращает указатель на предыдущий связанный входной поток (если он был) Вызов функции tie() без аргументов возвращает указатель на текзтций выходной поток данных, связанный с данным потоком. Чтобы связать поток данных с новым выходным потоком, следует передать указатель иа этот выходной поток в аргументе tie(). Аргумент является указателем, поскольку в нем также может передаваться О (илн NULL) для разрыва связи с выходным потоком данных. Каждый поток данных в любой момент времени может быть связан только с одним выходным потоком, но один выходной поток может быть связан с несколькими потоками данных. По умолчанию этот механизм используется для связывания стандартного входного потока данных со стандартным выходным потоком: Стандартные связи: std::Cin.t1e (&std:;COut); std::wcin.tie (&std::wcout); Тем самым гарантируется, что сообщение с запросом на ввод будет выведено из буфера перед операцией ввода. Например, при выполнении следзщего фрагмента перед чтением х для cout будет автоматически вызвана функция flush(): std::cout Please enter x: : std::cin X; Чтобы разорвать связь между потоками данных, передайте О или NULL при вызове tie(). Пример: Отсоединение cin от выходных потоков std::cin::tie (static cast<std::ostream*>(0)): Это может ускорить работу программы, поскольку позволяет избежать лишней очистки потоковых буферов (проблемы эффективности работы с потоками данных рассматриваются на с. 654). Выходной поток данных также можно связать с другим выходным потоком. Например, следующая команда указывает, что перед выводом каких-либо данных в сегг необходимо очистить буфер стандартного выходного потока данных: Связывание cout с сегг сегг.tie (&cout): Жесткое связывание с использованием потоковых буферов Функция rdbuf() осуществляет жесткое связывание потоков данных с помощью общего потокового буфера (табл. 13.38). Теблица 13.38. Работа с потоковыми буферами Функция Описание rdbuf() Возвращает указатель на потоковый буфер rdbuf(streambuf*) Назначает потоковый буфер, определяемый аргументом, и возвращает указатель на предыдущий потоковый буфер
|
© 2006 - 2025 pmbk.ru. Генерация страницы: 0.001
При копировании материалов приветствуются ссылки. |