В чем разница между istringstream, ostringstream и stringstream? / Почему бы не использовать stringstream в каждом случае? - PullRequest
143 голосов
/ 20 июля 2010

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

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

std::string stHehe("Hello ");

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

Ответы [ 8 ]

101 голосов
/ 20 июля 2010

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

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

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

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

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

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

std::string stHehe( "Hello stackoverflow.com!" );
20 голосов
/ 20 июля 2010

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

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

14 голосов
/ 20 июля 2010

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

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

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

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

5 голосов
/ 20 июля 2010

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

2 голосов
/ 20 июля 2010

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

1 голос
/ 20 июля 2010

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

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

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

0 голосов
/ 12 мая 2019

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

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

0 голосов
/ 20 июля 2010

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

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

...