Quelle est la différence entre istringstream, ostringstream et stringstream? / Pourquoi ne pas utiliser stringstream dans tous les cas?

163

Quand est-ce que j'utiliserais std::istringstream, std::ostringstreamet std::stringstreampourquoi ne devrais-je pas simplement utiliser std::stringstreamdans chaque scénario (y a-t-il des problèmes de performances d'exécution?).

Enfin, y a-t-il quelque chose de mauvais à ce sujet (au lieu d'utiliser un flux du tout):

std::string stHehe("Hello ");

stHehe += "stackoverflow.com";
stHehe += "!";
Oliver Baur
la source

Réponses:

119

Personnellement, je trouve très rare que je veuille effectuer du streaming dans et hors du même flux de chaînes.

Habituellement, je veux soit initialiser un flux à partir d'une chaîne, puis l'analyser; ou diffusez des éléments dans un flux de chaîne, puis extrayez le résultat et stockez-le.

Si vous diffusez depuis et vers le même flux, vous devez faire très attention à l'état du flux et aux positions des flux.

L' utilisation « juste » istringstreamou ostringstreamexprime mieux votre intention et vous donne une vérification contre des erreurs stupides, comme l' utilisation accidentelle de <<vs >>.

Il pourrait y avoir une amélioration des performances, mais je ne regarderais pas cela en premier.

Il n'y a rien de mal dans ce que vous avez écrit. Si vous trouvez que cela ne fonctionne pas assez bien, vous pouvez profiler d'autres approches, sinon vous en tenir à ce qui est le plus clair. Personnellement, j'irais simplement pour:

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

A stringstreamest un peu plus grand et peut avoir des performances légèrement inférieures - l'héritage multiple peut nécessiter un ajustement du pointeur vtable. La principale différence est (du moins en théorie) de mieux exprimer votre intention et de vous empêcher d'utiliser accidentellement >>là où vous le vouliez <<(ou vice versa). OTOH, la différence est suffisamment petite pour que, surtout pour les bits rapides de code de démonstration et autres, je suis paresseux et je ne fais que l'utiliser stringstream. Je ne me souviens pas très bien de la dernière fois que j'ai utilisé accidentellement <<quand je l'avais prévu >>, donc pour moi, ce peu de sécurité me semble surtout théorique (d'autant plus que si vous faites une telle erreur, cela sera presque toujours vraiment évident presque immédiatement).

Rien de mal à utiliser simplement une chaîne, tant qu'elle accomplit ce que vous voulez. Si vous ne faites que rassembler des chaînes, c'est facile et fonctionne bien. Si vous souhaitez formater d'autres types de données, a stringstreamle supportera, et une chaîne ne le sera généralement pas.

Jerry Coffin
la source
17

Dans la plupart des cas, vous n'aurez pas besoin à la fois d'entrée et de sortie sur le même flux de chaînes, donc utiliser std::ostringstreamet std::istringstreamclarifiera explicitement votre intention. Cela vous empêche également de saisir accidentellement le mauvais opérateur ( <<vs >>).

Lorsque vous devez effectuer les deux opérations sur le même flux, vous utilisez évidemment la version à usage général.

Les problèmes de performance seraient la moindre de vos préoccupations ici, la clarté est le principal avantage.

Enfin, il n'y a rien de mal à utiliser string append car vous devez construire des chaînes pures. Vous ne pouvez tout simplement pas utiliser cela pour combiner des nombres comme vous pouvez le faire dans des langages tels que perl.

Marque B
la source
8

istringstream est pour l'entrée, ostringstream pour la sortie. stringstream est l'entrée et la sortie. Vous pouvez utiliser stringstream à peu près partout. Cependant, si vous donnez votre objet à un autre utilisateur, et qu'il utilise l'opérateur >> alors que vous attendiez un objet en écriture seule, vous ne serez pas content ;-)

PS: rien de mal à ce sujet, juste des problèmes de performances.

Scharron
la source
2

Pour répondre à votre troisième question: non, c'est parfaitement raisonnable. L'avantage d'utiliser des flux est que vous pouvez entrer n'importe quelle sorte de valeur qui a un operator<<défini, alors que vous ne pouvez ajouter que des chaînes (C ++ ou C) à un fichier std::string.

David Thornley
la source
1

Vraisemblablement, lorsque seule l'insertion ou l'extraction est appropriée pour votre opération, vous pouvez utiliser l'une des versions préfixées «i» ou «o» pour exclure l'opération indésirable.

Si ce n'est pas important, vous pouvez utiliser la version i / o.

La concaténation de chaînes que vous affichez est parfaitement valide. Bien que la concaténation à l'aide de stringstream soit possible, ce n'est pas la fonctionnalité la plus utile des stringstreams, qui est de pouvoir insérer et extraire des types de données POD et abstraits.

Amardeep AC9MF
la source
1

std :: ostringstream :: str () crée une copie du contenu du flux, ce qui double l'utilisation de la mémoire dans certaines situations. Vous pouvez utiliser std :: stringstream et sa fonction rdbuf () à la place pour éviter cela.

Plus de détails ici: comment écrire ostringstream directement sur cout

Gerhard Wesp
la source
0

Pourquoi ouvrir un fichier pour un accès en lecture / écriture si vous n'avez besoin que d'en lire, par exemple?

Et si plusieurs processus devaient lire à partir du même fichier?

Assaf Lavie
la source