Какая разница между istringstream, ostringstream и stringstream?/Почему бы не использовать stringstream в каждом случае?

Когда я буду использовать std::istringstream, std::ostringstream и std::stringstream и почему я не должен просто использовать std::stringstream в каждом сценарии (есть ли проблемы производительности во время выполнения?).

Наконец, что-то плохое в этом (вместо использования потока вообще):

std::string stHehe("Hello ");

stHehe += "stackoverflow.com";
stHehe += "!";

Ответ 1

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

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

Если вы передаете потоки в один поток из одного потока, вы должны быть очень осторожны с положением потока и позициями потока.

Использование 'just' istringstream или ostringstream лучше выражает ваши намерения и дает вам некоторую проверку против глупых ошибок, таких как случайное использование << vs >>.

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

Нет ничего плохого в том, что вы написали. Если вы обнаружите, что он не работает достаточно хорошо, вы можете продумать другие подходы, иначе придерживайтесь того, что лучше всего. Лично я бы просто пошел за:

std::string stHehe( "Hello stackoverflow.com!" );

Ответ 2

A stringstream несколько больше и может иметь несколько более низкую производительность - для множественного наследования может потребоваться корректировка указателя vtable. Основное различие (по крайней мере теоретически) лучше выражает ваши намерения и предотвращает случайное использование >>, где вы намеревались << (или наоборот). OTOH, разница достаточно мала, что особенно для быстрых фрагментов демонстрационного кода и т.д., Я ленив и просто использую stringstream. Я не могу вспомнить последний раз, когда я случайно использовал <<, когда я намеревался >>, так что для меня эта битка безопасности кажется в основном теоретической (тем более, что если вы сделаете такую ​​ошибку, она почти всегда будет действительно очевидно почти сразу).

Ничего плохого в использовании строки, если она выполняет то, что вы хотите. Если вы просто вкладываете строки, это легко и прекрасно работает. Если вы хотите форматировать другие типы данных, то stringstream будет поддерживать это, а строка в основном не будет.

Ответ 3

В большинстве случаев вы не будете нуждаться как в вводе, так и в выходе в том же строке, поэтому использование std::ostringstream и std::istringstream явно делает ваше намерение ясным. Это также мешает вам случайно ввести неверный оператор (<< vs >>).

Если вам нужно выполнить обе операции в одном потоке, вы, очевидно, будете использовать версию общего назначения.

Проблемы с производительностью были бы наименьшей из ваших проблем здесь, ясность - главное преимущество.

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

Ответ 4

istringstream для ввода, ostringstream для вывода. stringstream - вход и выход. Вы можете использовать stringstream почти везде. Однако, если вы передаете свой объект другому пользователю и используете оператор → , тогда как вы ожидаете объект только для записи, вы не будете счастливы; -)

PS: ничего плохого в этом, просто проблемы с производительностью.

Ответ 5

Другие уже обработали stringstream vs. [i|o]stringstream достаточно хорошо; мне не нужно туда ехать.

Что касается std::string - ну, я не считаю, что у него есть операторы << или >>, поэтому вы не можете использовать его там, где может понадобиться поток файлов. Что еще более важно, я бы ожидал повторных и произвольных конкатенаций для std::string, чтобы иметь производительность O (N 2) или, в лучшем случае, производительность O (N * log (N)), причем разница заключается в том, насколько осторожен программист должен выделить лишнюю емкость в целевой строке. Тем не менее, N конкатенаций в ostringstream должны иметь производительность по O (N) (оставляя в стороне длину отдельных строк). Это может быть тривиальной разницей, когда вы объединяете только одну или две строки, а ostringstream может все еще медленнее, чем std::string, когда N мало. Но я знаю случаи, когда N был очень большим, и производительность O (N 2) действительно болела.

Ответ 6

Чтобы ответить на третий вопрос: Нет, это совершенно разумно. Преимущество использования потоков заключается в том, что вы можете ввести любое значение, которое получило operator<<, но вы можете добавлять строки (С++ или C) в std::string.

Ответ 7

Предположительно, если для вашей операции подходит только вставка или только извлечение, вы можете использовать одну из префиксных версий "i" или "o", чтобы исключить нежелательную операцию.

Если это не важно, вы можете использовать версию i/o.

Конкатенация строк, которую вы показываете, абсолютно корректна. Хотя возможна конкатенация с использованием строкового потока, которая не является самой полезной функцией строковых потоков, которая должна иметь возможность вставлять и извлекать POD и абстрактные типы данных.

Ответ 8

Зачем открывать файл для доступа для чтения и записи, если вам нужно только его прочитать?

Что делать, если несколько процессов необходимо читать из одного файла?

Ответ 9

std :: ostringstream :: str() создает копию содержимого потока, что удваивает использование памяти в некоторых ситуациях. Вы можете использовать std :: stringstream и его функцию rdbuf(), чтобы избежать этого.

Более подробно здесь: как написать ostringstream напрямую в cout