¿Cuál es la diferencia entre istringstream, ostringstream y stringstream? / ¿Por qué no usar stringstream en todos los casos?

163

Cuándo se debe utilizar std::istringstream, std::ostringstreamystd::stringstream y ¿por qué no yo sólo usostd::stringstream en cada escenario (¿Hay problemas de rendimiento en tiempo de ejecución?).

Por último, ¿hay algo malo en esto (en lugar de usar una transmisión):

std::string stHehe("Hello ");

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

Respuestas:

119

Personalmente, me parece muy raro que quiera realizar la transmisión dentro y fuera de la misma secuencia de cadena.

Por lo general, quiero inicializar una secuencia desde una cadena y luego analizarla; o transmitir cosas a una secuencia de cadena y luego extraer el resultado y almacenarlo.

Si está transmitiendo hacia y desde la misma transmisión, debe tener mucho cuidado con el estado de la transmisión y las posiciones de la transmisión.

El uso de 'sólo' istringstreamo ostringstreamexpresa mejor su intención y le da algunas comprobaciones contra errores tontos como el uso accidental de <<frente >>.

No podría haber alguna mejora en el rendimiento, pero no estaría mirando que en primer lugar.

No hay nada malo con lo que has escrito. Si encuentra que no funciona lo suficientemente bien, entonces podría perfilar otros enfoques, de lo contrario, seguir con lo que es más claro. Personalmente, solo iría por:

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

A stringstreames algo más grande y puede tener un rendimiento ligeramente inferior: la herencia múltiple puede requerir un ajuste en el puntero vtable. La principal diferencia es (al menos en teoría) mejor expresar su intención y evitar que use accidentalmente >>donde pretendía <<(o viceversa). OTOH, la diferencia es lo suficientemente pequeña que, especialmente para fragmentos rápidos de código de demostración y demás, soy flojo y solo lo uso stringstream. Yo no puedo recordar la última vez que utilicé accidentalmente <<cuando mi intención >>, por lo que a mí que algo de la seguridad parece prácticamente teórica (sobre todo porque si lo hace cometer un error, casi siempre va a ser muy evidente casi de inmediato).

No tiene nada de malo simplemente usar una cadena, siempre que logre lo que desea. Si solo está poniendo las cuerdas juntas, es fácil y funciona bien. Sin embargo, si desea formatear otros tipos de datos, a stringstreamlo admitirá y una cadena no lo hará.

Jerry Coffin
fuente
17

En la mayoría de los casos, no necesitará tanto entradas como salidas en el mismo flujo de cadena, por lo que usar std::ostringstreamy std::istringstreamexplícitamente aclara su intención. También evita que escribas accidentalmente el operador incorrecto ( <<vs >>).

Cuando necesite hacer ambas operaciones en la misma secuencia, obviamente usaría la versión de propósito general.

Los problemas de rendimiento serían la menor de sus preocupaciones aquí, la claridad es la principal ventaja.

Finalmente, no hay nada de malo en usar string append, ya que debes construir cadenas puras. Simplemente no puede usar eso para combinar números como puede hacerlo en idiomas como perl.

Mark B
fuente
8

istringstream es para entrada, ostringstream para salida. stringstream es entrada y salida. Puedes usar stringstream prácticamente en todas partes. Sin embargo, si le da su objeto a otro usuario y utiliza el operador >> mientras espera un objeto de solo escritura, no será feliz ;-)

PD: nada malo, solo problemas de rendimiento.

Scharron
fuente
2

Para responder a su tercera pregunta: No, eso es perfectamente razonable. La ventaja de usar secuencias es que puede ingresar cualquier tipo de valor que tenga operator<<definido, mientras que solo puede agregar cadenas (ya sea C ++ o C) a a std::string.

David Thornley
fuente
1

Presumiblemente, cuando solo la inserción o la extracción son apropiadas para su operación, podría usar una de las versiones prefijadas 'i' u 'o' para excluir la operación no deseada.

Si eso no es importante, puede usar la versión de E / S.

La concatenación de cadenas que está mostrando es perfectamente válida. Si bien es posible la concatenación con stringstream, esa no es la característica más útil de stringstreams, que es poder insertar y extraer POD y tipos de datos abstractos.

Amardeep AC9MF
fuente
1

std :: ostringstream :: str () crea una copia del contenido de la secuencia, que duplica el uso de memoria en algunas situaciones. Puede usar std :: stringstream y su función rdbuf () en su lugar para evitar esto.

Más detalles aquí: cómo escribir ostringstream directamente en cout

Gerhard Wesp
fuente
0

¿Por qué abrir un archivo para acceso de lectura / escritura si solo necesita leer de él, por ejemplo?

¿Qué pasa si se necesitan varios procesos para leer desde el mismo archivo?

Assaf Lavie
fuente