Программирование >>  Операторы преобразования типа 

1 ... 195 196 197 [ 198 ] 199 200 201 ... 239


Следующий пример демонстрирует использование функции 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*) Назначает потоковый буфер, определяемый аргументом, и возвращает указатель на предыдущий потоковый буфер



1 ... 195 196 197 [ 198 ] 199 200 201 ... 239

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