Qual é a diferença entre istringstream, ostringstream e stringstream? / Por que não usar stringstream em todos os casos?

163

Quando devo usar std::istringstream, std::ostringstreame std::stringstreame por que não devo apenas usar std::stringstreamem todos os cenários (existem quaisquer problemas de desempenho de tempo de execução?).

Por fim, há algo de ruim nisso (em vez de usar um fluxo):

std::string stHehe("Hello ");

stHehe += "stackoverflow.com";
stHehe += "!";
Oliver Baur
fonte

Respostas:

119

Pessoalmente, acho muito raro que eu queira executar streaming dentro e fora do mesmo fluxo de string.

Normalmente, eu quero inicializar um fluxo a partir de uma string e analisá-lo; ou transmitir coisas para um fluxo de string e extrair o resultado e armazená-lo.

Se você estiver transmitindo de e para o mesmo fluxo, você deve ter muito cuidado com o estado e as posições do fluxo.

Usando 'apenas' istringstreamou ostringstreamexpressa melhor a sua intenção e dá-lhe alguns testes contra erros bobos como o uso acidental de <<vs >>.

Não pode haver alguma melhora o desempenho, mas eu não iria estar a olhar para isso primeiro.

Não há nada errado com o que você escreveu. Se você achar que o desempenho não é bom o suficiente, poderá criar um perfil de outras abordagens, caso contrário, fique com o que for mais claro. Pessoalmente, eu gostaria de:

std::string stHehe( "Hello stackoverflow.com!" );
CB Bailey
fonte
22

A stringstreamé um pouco maior e pode ter um desempenho um pouco menor - a herança múltipla pode exigir um ajuste no ponteiro da tabela. A principal diferença é (pelo menos em teoria) expressar melhor sua intenção e impedir que você use acidentalmente >>onde pretendia <<(ou vice-versa). OTOH, a diferença é suficientemente pequena que, especialmente para bits rápidos de código de demonstração, eu sou preguiçosa e apenas uso stringstream. Eu não consigo me lembrar da última vez que eu usei acidentalmente <<quando eu pretendia >>, então para mim que pouco de segurança parece mais teórico (especialmente desde que se faça fazer tal erro, vai ser quase sempre muito óbvio quase imediatamente).

Nada de errado em usar apenas uma string, desde que ela atinja o que você deseja. Se você está apenas juntando as cordas, é fácil e funciona bem. Se você deseja formatar outros tipos de dados, o a stringstreamsuporta isso, e a string geralmente não.

Jerry Coffin
fonte
17

Na maioria dos casos, você não precisará da entrada e da saída no mesmo fluxo de string, portanto, usar std::ostringstreame std::istringstreamexplicitar claramente sua intenção. Também impede que você digite acidentalmente o operador errado ( <<vs >>).

Quando você precisa executar as duas operações no mesmo fluxo, obviamente usaria a versão de uso geral.

Os problemas de desempenho seriam a menor das suas preocupações aqui; a clareza é a principal vantagem.

Finalmente, não há nada de errado em usar o apêndice de cadeia, pois você precisa construir cadeias de caracteres puras. Você simplesmente não pode usar isso para combinar números como você pode em idiomas como o perl.

Mark B
fonte
8

istringstream é para entrada, ostringstream para saída. stringstream é entrada e saída. Você pode usar o stringstream praticamente em qualquer lugar. No entanto, se você der seu objeto a outro usuário e ele usar o operador >>, enquanto você espera um objeto somente para gravação, não ficará feliz ;-)

PS: nada de ruim nisso, apenas problemas de desempenho.

Scharron
fonte
2

Para responder à sua terceira pergunta: Não, isso é perfeitamente razoável. A vantagem de usar fluxos é que você pode inserir qualquer tipo de valor que tenha um operator<<definido, enquanto você pode adicionar apenas cadeias (C ++ ou C) a um std::string.

David Thornley
fonte
1

Presumivelmente, quando apenas a inserção ou extração é apropriada para sua operação, você pode usar uma das versões prefixadas 'i' ou 'o' para excluir a operação indesejada.

Se isso não for importante, você poderá usar a versão de E / S.

A concatenação de strings que você está mostrando é perfeitamente válida. Embora a concatenação usando stringstream seja possível, esse não é o recurso mais útil dos strings, que deve ser capaz de inserir e extrair POD e abstrair tipos de dados.

Amardeep AC9MF
fonte
1

std :: ostringstream :: str () cria uma cópia do conteúdo do fluxo, que dobra o uso da memória em algumas situações. Você pode usar std :: stringstream e sua função rdbuf () para evitar isso.

Mais detalhes aqui: como escrever ostringstream diretamente no cout

Gerhard Wesp
fonte
0

Por que abrir um arquivo para acesso de leitura / gravação, se você só precisa ler, por exemplo?

E se vários processos precisassem ler do mesmo arquivo?

Assaf Lavie
fonte