Строковые потоки stringstream
Аналогично функциям sscanf и sprintf в языке C, в языке C++ есть возможность считывать данные из строк (как будто бы из файла) и выводить данные в строки.
Для этого используются описанные в заголовочном файле sstream объекты istringstream (поток для чтения из строки) и ostringstream(поток для вывода из строки).
Приведем пример использования этих потоков. Пусть в строке s записано два числа через пробел, мы считаем их при используя объект istringstream, связанный со строкой, затем выведем в объект ostringstream эти же числа, увеличенные на 1 и скопируем результат в строку s.
Класс basic_istringstream
Описывает объект, который управляет извлечением элементов и закодированными объектами из буфера потока класса basic_stringbuf<Elem, Tr, Alloc >.
Синтаксис
Параметры
Alloc
Класс распределителя.
Elem
Тип основного элемента строки.
Tr
Признаки символа, соответствующие основному элементу строки.
Remarks
Шаблон класса описывает объект, который управляет извлечением элементов и закодированными объектами из буфера потока класса basic_stringbuf<Elem, Tr, Alloc >с элементами типа Elem, признаки символов которого определяются классом Tr, и элементы которого выделяются распределителем класса Alloc. Объект сохраняет объект класса basic_stringbuf<Elem, Tr, Alloc >.
Конструкторы
| Конструктор | Описание |
|---|---|
| basic_istringstream | Создает объект типа basic_istringstream . |
Определения типов
| Имя типа | Описание |
|---|---|
| allocator_type | Этот тип является синонимом для параметра шаблона Alloc . |
Функции элементов
| Функция-член | Описание |
|---|---|
| rdbuf | Возвращает адрес сохраненного буфера потока типа pointer для basic_stringbuf< Elem , Tr , . Alloc > |
| str | Задает или получает текст в буфере строк без изменения позиции записи. |
| swap | Меняет местами значения в этом объекте basic_istringstream и значения предоставленного объекта. |
Операторы
| Оператор | Описание |
|---|---|
| оператор= | Назначает значения этому объекту basic_istringstream из параметра объекта. |
Требования
Заголовка:< sstream>
Пространство имен: std
basic_istringstream::allocator_type
Этот тип является синонимом для параметра шаблона Alloc .
basic_istringstream::basic_istringstream
Создает объект типа basic_istringstream .
Параметры
str
Объект типа basic_string .
right
Ссылка rvalue на объект basic_istringstream .
Remarks
Первый конструктор инициализирует базовый класс путем вызова basic_istream]( sb ) , где sb находится хранимый объект класса basic_stringbuf< Elem, Tr, Alloc> . Он также инициализируется sb путем вызова basic_stringbuf< Elem, Tr, Alloc >( _Mode | ios_base::in ) . Дополнительные сведения см. в разделах basic_istream и basic_stringbuf .
Второй конструктор инициализирует базовый класс путем вызова basic_istream( sb ) . Он также инициализируется sb путем вызова basic_stringbuf< Elem, Tr, Alloc >( str, _Mode | ios_base::in ) .
Третий конструктор инициализирует объект с содержимым справа, который рассматривается как ссылка rvalue.
basic_istringstream::operator=
Назначает значения этому объекту basic_istringstream из параметра объекта.
Параметры
right
Ссылка rvalue на объект basic_istringstream .
Remarks
Оператор-член заменяет содержимое объекта содержимым справа, обрабатываемым как назначение перемещения ссылки rvalue.
basic_istringstream::rdbuf
Возвращает адрес сохраненного буфера потока типа pointer basic_stringbuf<Elem, Tr, Alloc >.
Возвращаемое значение
Адрес сохраненного буфера потока типа pointer для basic_stringbuf<Elem, Tr, Alloc >.
Пример
Пример, в котором используется rdbuf , см. в разделе basic_filebuf::close.
basic_istringstream::str
Задает или получает текст в буфере строк без изменения позиции записи.
Параметры
_Newstr
Новая строка.
Возвращаемое значение
Возвращает объект класса basic_string<Elem, Tr, у которого управляемая последовательность является копией последовательности, Alloc >управляемой *this.
Remarks
Первая функция-член возвращает rdbuf ->str. Вторая функция-член вызывает rdbuf ->str( _Newstr ).
Пример
basic_istringstream::swap
Меняет местами значения двух объектов basic_istringstream .
Параметры
right
Ссылка lvalue на объект basic_istringstream .
Remarks
Функция-член обменивается значениями этого объекта и значениями справа.
std::stringstream и форматирование строк
Ввод и вывод информации — критически важная задача, без выполнения которой любая программа становится бесполезной. В C++ для решения данной задачи традиционно применяются потоки ввода-вывода, которые реализованы в стандартной библиотеке IOStream.
Плюсами такого подхода являются:
— универсальность: не важно, с чем связан поток, — ввод-вывод с консоли, файла, сокета, процесса происходит одинаково;
— прозрачность: программисту не нужно явно указывать тип вводимого или выводимого объекта;
— расширяемость: программист может добавить поддержку ввода-вывода в поток для любого своего объекта, просто перегрузив соответствующие операторы.
В библиотеке IOStream есть также класс stringstream , который позволяет связать поток ввода-вывода со строкой в памяти. Всё, что выводится в такой поток, добавляется в конец строки; всё, что считыватся из потока — извлекается из начала строки.
Он позволяет делать весьма забавные вещи, например, осуществлять преобразование типов:
Кроме того, этот класс можно использовать для форматирования сложных строк, например:
Понятно, что в данном случае использование stringstream излишне, так как сообщение можно было выводить напрямую в cerr . Но что если вы хотите вывести сообщение не в стандартный поток, а использовать, скажем, функцию syslog() для вывода сообщения в системный журнал? Или, скажем, сгенерировать исключение, содержащее данную строку как пояснение:
Получается, вам необходим промежуточный объект stringstream , в котором вы сначала формируете строку, а затем получаете её с помощью метода str() . Согласитесь, громоздко?
C++ порой винят за его чрезмерную сложность и избыточность, которые, однако, в ряде случаев позволяют создавать весьма изящные конструкции. Вот и сейчас, шаблоны и возможность перегрузки операторов помогли мне создать обёртку над stringstream , которая позволяет форматировать строку в любом месте кода без дополнительных переменных как если бы я просто выводил данные в поток:
А вот и сам MakeString :
Работает это очень просто. С одной стороны, в классе MakeString перегружен оператор вывода (<<), который принимает в качестве аргумента константную ссылку на объект любого типа, тут же выводит этот объект в свой внутренний stringstream и возвращает ссылку на себя. С другой стороны, перегружен оператор преобразования к строке, который возвращает строку, сформированную stringstream ‘ом.
Быть может, кому-то эта обёртка окажется полезной. Буду рад услышать комментарии, предложения и пожелания.