stringstream c что это

О строковом форматировании в современном C++

Доброго времени суток! В этой статье я хотел бы рассказать о существующих возможностях строкового форматирования в современном C++, показать свои наработки, которые я уже несколько лет использую в реальных проектах, а также сравнить производительность различных подходов к строковому форматированию.

Строковое форматирование — это операция, позволяющая получить результирующую строку из строки-шаблона и набора аргументов. Строка-шаблон содержит текст, в который включены местозаполнители (placeholders), вместо которых подставляются аргументы.

Для наглядности небольшой пример:

Здесь:
Строка-шаблон: I have %d apples and %d oranges, so I have %d fruits
Местозаполнители: %d, %d, %d
Аргументы: apples, oranges, apples + oranges

При выполнении примера, получаем результирующую строку

Теперь посмотрим, что же нам предоставляет C++ для строкового форматирования.

Наследие C

Строковое форматирование в C осуществляется с помощью семейства функций Xprintf. С тем же успехом, мы можем воспользоваться этими функциями и в C++:

Это довольно неплохой способ форматирования, несмотря на кажущуюся неуклюжесть:

Но, конечно, не обошлось и без недостатков:

Функция std::to_string()

Начиная с C++11 в стандартной библиотеке появилась функция std::to_string(), которая позволяет преобразовать передаваемое значение в строку. Функция работает не со всеми типами аргументов, а только со следующими:

Класс std::stringstream

Класс std::stringstream — это основной способ строкового форматирования, который нам предоставляет C++:

Строго говоря, использование std::stringstream не является в полной мере строковым форматированием, так как вместо местозаполнителей мы вставляем в строку-шаблон аргументы. Это допустимо в простейших случаях, но в более сложных существенно ухудшает читаемость кода:

Объект std::sringstream позволяет реализовать несколько интересных оберток, которые могут понадобится в дальнейшем.

Преобразование «чего угодно» в строку:

Преобразование строки во «что угодно»:

Преобразование строки во «что угодно» с проверкой:

Также, можно написать пару оберток для удобного использования std::stringstream в одну строку.

Использование объекта std::stringstream для каждого аргумента:

Использование одного объекта std::stringstream для всей строки:

Забегая вперед, оказывается, что производительность std::to_string в 3-4 раза выше, чем у to_string, реализованной с помощью std::stringstream. Поэтому, логично будет использовать std::to_string для подходящих типов, а для всех остальных использовать шаблонную to_string:

Библиотека boost::format

Набор библиотек boost является мощным средством, отлично дополняющим средства языка C++ и стандартной библиотеки. Строковое форматирование представлено библиотекой boost::format.

Поддерживается указание как типовых местозаполнителей:

Единственный недостаток boost::format — низкая производительность, это самый медленный способ строкового форматирования. Также этот способ неприменим, если в проекте нельзя использовать сторонние библиотеки.

Итак, получается, что C++ и стандартная библиотека не предоставляют нам удобных средств строкового форматирования, поэтому будем писать что-то свое.

Обертка над vsnprintf

Попробуем написать обертку над Xprintf функцией, выделяя достаточно памяти и передавая произвольное количество параметров.

Для выделения памяти будем использовать следующую стратегию:

Для передачи параметров будем использовать механизм stdarg и функцию vsnprintf.

Шаблон с переменным количеством аргументов (Variadic Template)

В C++ начиная с C++11 появилась возможность использовать шаблоны с переменным количеством аргументов (Variadic Templates).

Такие шаблоны можно использовать при передаче аргументов в функцию форматирования. Также, нам больше не нужно заботиться о типах аргументов, так как мы можем использовать шаблонную to_string, которая была реализована ранее. Поэтому будем использовать порядковые местозаполнители.

Для получения всех аргументов отделяем первый аргумент, преобразуем его в строку, запоминаем и рекурсивно повторяем эту операцию. В случае отсутствия аргументов или при их окончании (конечная точка рекурсии) выполняем разбор строки-шаблона, подстановку аргументов и получаем результирующую строку.

Таким образом, у нас есть все, чтобы полностью реализовать функцию форматирования: парсинг строки-шаблона, сбор и преобразование в строку всех параметров, подстановку параметров в строку-шаблон и получение результирующей строки:

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

Сравнение производительности

Сравнение производительности to_string и std::to_string, миллисекунд на миллион вызовов

int, мсlong long, мсdouble, мс
to_string6817041109
std::to_string130201291

stringstream c что это. Смотреть фото stringstream c что это. Смотреть картинку stringstream c что это. Картинка про stringstream c что это. Фото stringstream c что это

Сравнение производительности функций форматирования, миллисекунд на миллион вызовов

мс
fstr1308
sstr1243
format788
boost::format2554
vtformat2022

stringstream c что это. Смотреть фото stringstream c что это. Смотреть картинку stringstream c что это. Картинка про stringstream c что это. Фото stringstream c что это

Спасибо за внимание. Замечания и дополнения приветствуются.

Источник

Что именно делает stringstream?

Со вчерашнего дня я пытаюсь выучить C ++ и использую этот документ:http://www.cplusplus.com/files/tutorial.pdf (стр. 32). Я нашел код в документе и запустил его. Я попытался ввести Rs 5,5 для цены и целое число для количества, и результат был 0.
Я попытался ввести 5,5 и 6, и вывод был правильным.

Вопрос: Что именно делает команда mystring? Цитата из документа:

«В этом примере мы получаем числовые значения из стандартного ввода
косвенно. Вместо того, чтобы извлекать числовые значения непосредственно из
стандартный ввод, мы получаем строки из стандартного ввода (CIN) в
строковый объект (mystr), а затем мы извлекаем целочисленные значения из
эту строку в переменную типа int (количество). «

У меня сложилось впечатление, что функция будет принимать неотъемлемую часть строки и использовать ее в качестве входных данных.

(Я точно не знаю, как задать вопрос здесь. Я также новичок в программировании)
Спасибо.

Решение

Иногда очень удобно использовать поток строк для преобразования между строками и другими числовыми типами. Использование stringstream похоже на использование iostream так что не бремя учиться.

Строковые потоки могут использоваться как для чтения строк, так и для записи данных в строки. Он в основном работает со строковым буфером, но без реального канала ввода-вывода.

Основные функции-члены класса stringstream:

Вот пример того, как использовать строковые потоки.

istringstream более или менее того же использования.

Подводя итог, струнный поток является удобным способом манипулировать строками как независимое устройство ввода / вывода.

К вашему сведению, отношения наследования между классами:

stringstream c что это. Смотреть фото stringstream c что это. Смотреть картинку stringstream c что это. Картинка про stringstream c что это. Фото stringstream c что это

Другие решения

Ответить на вопрос. stringstream в основном позволяет лечить string объект как stream и использовать все stream функции и операторы на нем.

Я видел, что он используется в основном для форматированного вывода / ввода совершенства.

Один хороший пример будет c++ реализация преобразования номера в потоковый объект.

Также в этом примере string буфер скрыт и не используется явно. Но было бы слишком долго писать о каждом возможном аспекте и сценарии использования.

Примечание: я, вероятно, украл его у кого-то на SO и уточнил, но у меня нет оригинального автора.

istringstream тип читает строка, ostringstream пишет строка, а также stringstream читает и пишет строка.

Я сталкиваюсь с некоторыми случаями, когда это удобно и кратко использовать stringstream.

Случай 1

предполагать a а также b комплексные числа, выраженные в строковом формате, мы хотим получить результат умножения a а также b также в строковом формате. Код выглядит следующим образом:

случай 2

Это также из проблема кода что требует от вас упростить заданную строку пути, одно из решений с использованием stringstream самое элегантное, что я видел:

Без использования stringstream было бы сложно написать такой лаконичный код.

Первым токеном был RS, который не удалось преобразовать в int оставляя ноль для myprice, и мы все знаем, что ноль раз что-либо дает.

Когда вы только ввели значения int во второй раз, все работало так, как вы ожидали.

Это была ложная RS, которая вызвала сбой вашего кода.

Источник

std:: basic_stringstream

Compiler support
Freestanding and hosted
Language
Standard library headers
Named requirements
Feature test macros (C++20)
Language support library
Concepts library (C++20)
Diagnostics library
General utilities library
Strings library
Containers library
Iterators library
Ranges library (C++20)
Algorithms library
Numerics library
Localizations library
Input/output library
Filesystem library (C++17)
Regular expressions library (C++11)
Atomic operations library (C++11)
Thread support library (C++11)
Technical specifications
Symbols index
External libraries

The class template std::basic_stringstream implements input and output operations on string based streams. It effectively stores an instance of std::basic_string and performs the input and output operations on it.

stringstream c что это. Смотреть фото stringstream c что это. Смотреть картинку stringstream c что это. Картинка про stringstream c что это. Фото stringstream c что это

Two specializations for common character types are also defined:

Источник

Использование stringstream

Stringstream C++
Доброго времени суток! Совсем недавно мне понадобились преобразования int to string и наоборот.

Stringstream и оператор >>
Доброго времени. Код: #include #include using namespace std; int.

Std::stringstream
Добрый день! Я не понимаю почему я ввожу в поток std::stringstream три элемента, число, строку и.

Ипользование класса stringstream
Всем привет. Дело такое: задача одного из моих методов класса запросить вводи имени клиента и его.

не обновляет содержимое x.
Читал в доке, что ss.clear() сбрасывает флаги. И только.

Как правильно использовать stringstream?
Может быть, уничтожать и создавать заново каждый раз?

Добавлено через 1 минуту
Извиняюсь за растянутое вступление, просто первый пост, я его набрал весь полностью некоторое время назад, а он пропал.

Добавлено через 26 минут
Нашел ответ в соседней ветке.

Добавлено через 1 час 18 минут
Кстати, может быть, кто-нибудь знает, как в gdb вывести содержимое stringstream?

Добавлено через 10 минут
Нет, не работает и так.
Ситуация следующая.
В Buf записан один символ, не считая конца строки:

содержимое х остается старым.

Какие есть альтернативы для разделения строки на слова?

Если кому интересно, компилирую на Линуксе RH6.6
g++ (GCC) 4.4.7 20120313 (Red Hat 4.4.7-11)

Источник

Класс basic_stringstream

Описывает объект, управляющий вставкой и извлечением элементов и закодированных объектов с помощью буфера потока класса basic_stringbuf Alloc >.

Синтаксис

Параметры

Идентификатор
Класс распределителя.

Elem
Тип основного элемента строки.

ТС
Признаки символа, соответствующие основному элементу строки.

Remarks

Конструкторы

Определения типов

Функции элементов

Требования

Заголовок:

Пространство имен: std

basic_stringstream:: allocator_type

basic_stringstream:: basic_stringstream

Параметры

Remarks

Первый конструктор инициализирует базовый класс путем вызова basic_iostream( SB), где sb — это сохраненный объект класса basic_stringbuf Alloc >. Он также инициализируется sb путем вызова basic_stringbuf Alloc > ( _Mode ).

Второй конструктор инициализирует базовый класс путем вызова basic_iostream( sb). Он также инициализируется sb путем вызова basic_stringbuf Alloc > (_ str, _Mode ).

basic_stringstream:: rdbuf

Возвращает адрес буфера сохраненного потока типа pointer в basic_stringbuf Alloc >.

Возвращаемое значение

Адрес буфера сохраненного потока типа pointer для basic_stringbuf Alloc >.

Пример

basic_stringstream:: str

Задает или получает текст в буфере строк без изменения позиции записи.

Параметры

_Newstr
Новая строка.

Возвращаемое значение

Возвращает объект класса basic_string Alloc >, управляемой последовательностью которого является копия последовательности, управляемой * этим объектом.

Remarks

Пример

Источник

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *