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

1 ... 205 206 207 [ 208 ] 209 210 211 ... 239


тором по згмолчанию. Кроме того, итератор istreambuf iterator устанавливается в конец потока данных при попытке вывести итератор за конец потока (то есть когда SbumpcO возвращает traits type; :еоО- У такого поведения имеются два важных следствия.

О Интервал от текущей позиции до конца потока данных определяется двумя итераторами istreambufJterator<charT,traits>(womoK) (текущая позиция) и istreambufJterator<charT,traits>0 (конец потока) где поток относится к типу basicJstream<charT,traits> или basic streambuf<charT,traits>.

О Класс Istreambufjterator не позволяет создавать подинтервалы.

Пример использования итераторов потоковых буферов

Далее представлен классический фильтр, который просто выводит все прочитанные символы при помощи итераторов потоковых буферов. Он представляет собой видоизмененную версию примера, показанного на с. 586:

io/charcat2.cpp Iinclude <iostream> Iinclude <iterator> using namespace std:

int mainO {

Итератор потокового буфера ввода для cin i streambufj terator<char> 1npos(ci n):

Итератор конца потока

1streambuf iterator<char> endpos:

Итератор потокового буфера вывода для cout ostreambuf 1terator<char> outpos(cout):

Пока итератор ввода остается действительным while (inpos !- endpos) {

*outpos - *inpos: Присвоить его значение итератору вывода

++inpos:

++outpos;

1ользовательские потоковые буферы

Потоковые буферы предназначены для выполнения ввода-вывода, а их интерфейс определяется классом baslc streambuf. Для типов символов char и wchar t определены специализации streambuf и wstreambuf. Эти классы используются в качестве базовых при реализации взаимодействий через специальные каналы ввода-вывода, однако для этого необходимо хорошо понимать принципы работы потоковых буферов.



Цергфальный интерфейс буферов состоит из трех указателей для каждого из двух буферов. Указатели, возвращаемые функциями еЬаск(), gptr() и egptr(), образуют интерфейс к буферу чтения. Указатели, возвращаемые функциями pbaseO, pptr() и epptr(), образуют интерфейс к буферу записи. Операции чтения и записи работают с этими указателями, что приводит к соответствующей реакции в канале ввода или вывода. Далее операции чтения и записи рассматриваются отдельно.

Пользовательские буферы вывода

Для буфера, используемого для записи символов, поддерживаются три указателя, которые могут быть ползены функциями pbase(), pptr() и epptr() (рис. 13.4):

О pbaseO (*база вывода -) - определяет начало буфера вывода;

О pptr() ( указатель вывода ) - определяет текущую позицию записи;

О epptr() ( конец вывода ) - определяет конец буфера вывода, то есть позицию, следующую за последним буферизуемым символом.

рЬа8 ()

PptrO

PPtrO

Рис. 13.4. Интерфейс буферов вывода

Символы в интервале от pbase() до pptr() (не включая символ, на который ссылается pptr()) уже записаны, но еще не выведены в соответствующий канал вывода.

Символы записываются в буфер функцией sputc(). Символ копируется в текущую позицию записи (при наличии свободной позиции), после чего указатель на текущую позицию записи увеличивается. Если буфер полон (pptr()=epptr()), то содержимое буфера вывода посылается в соответствующий канал вывода вызовом виртуальной ф)шкции overflow(). Эта функция фактически отвечает за непосредственную передачу символов некоторому внешнему представлению (которое на самом деле может быть внутренним, как в случае со строковыми потоками данных). Реализация overflow() в базовом классе basic streambuf возвращает только признак конца файла, означающий, что дальнейшая запись символов невозможна.

Функция sputn() позволяет записать сразу несколько символов. Она перепоручает работу виртуальной функции xsputn(), которая может оптимизироваться для более эффективной записи нескольких символов. Реализация xsputn() в классе basic streambuf вызывает sputc() для каждого символа, поэтому в ее переопределении нет абсолютной необходимости. Тем не менее в некоторых случаях запись нескольких символов реализуется более эффективно, чем последовательная запись отдельных символов, а фзгнкция xsputn() помогает оптимизировать обработку символьных последовательностей.

Запись в потоковый буфер может выполняться и без буферизации - вместо этого символы выводятся сразу же после их получения. В этом случае указате-



лям буфера вывода присваивается значение О или NULL. Конструктор по умолчанию делает это автоматически.

На основе изложенного материала был разработан следующий пример потокового буфера, не использующего буферизацию. То есть для каждого символа вызывается функция overflow(). Остается лишь реализовать эту функцию.

io/outbufl.hpp Iinclude <streafiibuf> Iinclude <locale> Iinclude <cstdio>

class outbuf : public std;:streambuf

protected: /* Главная функция вывода * - вывод символов в верхнем регистре */

virtual int type overflow (int type c) { if (c != EOF) {

Преобразование символа к верхнему регистру с - std: :toupper(c.getlocO);

Запись символа в стандартный вывод if (putchar(c) =- EOF) { return EOF;

return c:

В данном случае каждый символ, передаваемый в потоковый буфер, записывается функцией putcharO языка С. Но перед выводом символ преобразуется к верхнему регистру функцией toupper() (см. с. 692). Функция getioc() возвращает объект локального контекста, связанный с потоковым буфером (см. с. 637).

В представленном примере буфер вывода реализован специально для типа char (streambuf - специализация basic streambuf для типа символов char). При использовании другого типа символов зту функцию следует реализовать с применением класса трактовок символов, представленного на с. 659. В этом случае сравнение с с концом файла вьшолняется иначе. Вместо EOF должно возвращаться значение traits eof(), а если аргумент с равен EOF, следует возвращать traits: :not eof(c) (где traits - второй аргумент шаблона basic streambuf). Возможная реализация выглядит так:

io/outbuflx.hpp Iinclude <streambuf> Iinclude <locale> Iinclude <cstd1o>

template <class charT. class traits - stdi:char traits<charT> > class basic outbuf : public std::basic streambuf<charT.traits>



1 ... 205 206 207 [ 208 ] 209 210 211 ... 239

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