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

163

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

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

std::string stHehe("Hello ");

stHehe += "stackoverflow.com";
stHehe += "!";
Оливер Баур
источник

Ответы:

119

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

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

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

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

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

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

std::string stHehe( "Hello stackoverflow.com!" );
CB Bailey
источник
22

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

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

Джерри Гроб
источник
17

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

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

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

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

Марк Б
источник
9

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

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

Scharron
источник
2

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

Дэвид Торнли
источник
1

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

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

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

Amardeep AC9MF
источник
1

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

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

Герхард Вест
источник
0

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

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

Ассаф Лави
источник