¿Cómo se borra una variable de secuencia de cadena?

486

Ya he probado varias cosas,

std::stringstream m;
m.empty();
m.clear();

los cuales no funcionan.

CodificaciónSin Comentarios
fuente

Respuestas:

771

Para todos los tipos de biblioteca estándar, la función miembro empty()es una consulta, no un comando, es decir, "¿estás vacío?" no "por favor, deseche sus contenidos".

La clear()función miembro se hereda iosy se utiliza para borrar el estado de error de la secuencia, por ejemplo, si una secuencia de archivo tiene el estado de error establecido en eofbit(fin de archivo), la llamada clear()volverá a establecer el estado de error en goodbit(sin error) .

Para borrar el contenido de a stringstream, use:

m.str("");

es correcto, aunque usando:

m.str(std::string());

es técnicamente más eficiente, porque evita invocar al std::stringconstructor que toma const char*. Pero cualquier compilador en estos días debería ser capaz de generar el mismo código en ambos casos, por lo que simplemente elegiría lo que sea más legible.

Wilka
fuente
105
Esto es lo que sucede cuando olvida la parte "clear ()". stackoverflow.com/q/2848087/635549
galath
8
@KshitijBanerjee Creo que en C ++ m.str () y m.str ("") son dos funciones diferentes. m.str () invoca una función que no esperaba ningún parámetro, mientras que m.str ("") invocará la función que acepta un parámetro const char *. m.str () podría haberse implementado como una función get que devuelve la cadena, mientras que m.str ("") podría haberse implementado como una función de conjunto .
Dinesh PR
44
Como dijo Galath, es muy importante también agregar m.clear (); además de m.str ("") ;. De lo contrario, puede tener problemas si en algún momento llena el flujo de cadena con una cadena vacía.
Sputnik
1
@anthropod Sí, eso fue el año pasado. Desde entonces lo tengo funcionando.
James
1
Oh chico es así de intuitivo. ¡Como todo lo demás sobre C ++!
luna soleada el
47

Puede borrar el estado de error y vaciar el flujo de cadena todo en una línea

std::stringstream().swap(m); // swap m with a default constructed stringstream

Esto restablece efectivamente m a un estado construido por defecto

Nikos Athanasiou
fuente
3
Esta es la forma más eficiente y elegante de hacerlo en comparación con todas las otras respuestas aquí. Sin embargo, std :: stringstream :: swap es una característica de c ++ 11 y esta solución no funciona para compiladores anteriores de c ++ 11.
101010
44
Todavía falta la función en GNU g ++ v4.8, consulte stackoverflow.com/questions/24429441/…
Joachim W
77
@ 101010: ¿Cómo es mejor el intercambio que la asignación de movimiento?
Deduplicador el
2
@AsetD: Incluso si no es excepto, ¿olvidó el temporal construido por defecto?
Deduplicador
3
Esto es poco eficiente. Cuando quiero volver a usar ss original. Cambia un vacío por mí.
Zhang
36
m.str("");

parece funcionar.

CodificaciónSin Comentarios
fuente
3
Eso sería despejado por .clear (), que se especifica en el OP.
Dave Lugg
33

Esta debería ser la forma más confiable, independientemente del compilador:

m=std::stringstream();
jerron
fuente
2
Esto es mejor en mi opinión porque m.str (""); hizo que mi secuencia de cadena se atascara con ese valor vacío, lo que sea que intenté. Pero usando esto no tengo ese problema
gelatina1
3
Me encontré con el mismo problema, para mí mm.clear(); mm.str("");hice el truco. (sin C ++ 11, de lo contrario, el intercambio sería mejor).
hochl
1
@hochl: ¿Por qué sería swapmejor que la asignación de movimiento?
Deduplicador el
44
No es bueno para toda situación. Esto reasignaría el búfer cada vez que mm.str ("") no lo haría.
Shital Shah
3
Mi caso de uso principal para enjuagar un objeto de secuencia de cadena es mantener un objeto de secuencia de secuencia local de hilo alrededor para evitar la creación de instancias innecesaria de la secuencia de secuencia - instanciar un nuevo objeto de secuencia de secuencia copia el objeto de localización global - teóricamente esto es rápido y solo implica incrementar un atómico, pero a nivel de concurrencia con la que trato es a menudo paralizante.
Spacemoose
12

Siempre lo estoy analizando:

{
    std::stringstream ss;
    ss << "what";
}

{
    std::stringstream ss;
    ss << "the";
}

{
    std::stringstream ss;
    ss << "heck";
}
TimoK
fuente
1
¿Es esto mejor que limpiar elstringstream?
Robur_131
11

mis 2 centavos:

esto parecía funcionar para mí en xcode y dev-c ++, tenía un programa en forma de menú que, si se ejecutaba iterativamente según la solicitud de un usuario, llenaría una variable de secuencia de cadena que funcionaría bien la primera vez que el código ejecutar pero no borraría el flujo de cadena la próxima vez que el usuario ejecute el mismo código. pero las dos líneas de código a continuación finalmente borraron la variable de secuencia de cadena cada vez antes de llenar la variable de cadena. (2 horas de prueba y error y búsquedas en google), por cierto, usar cada línea por sí solo no funcionaría.

//clear the stringstream variable

sstm.str("");
sstm.clear();

//fill up the streamstream variable
sstm << "crap" << "morecrap";
Francisco Cortes
fuente
-1

Es un problema conceptual.

Stringstream es un flujo, por lo que sus iteradores son hacia adelante, no pueden regresar. En un flujo de cadena de salida, necesita un flush () para reinicializarlo, como en cualquier otro flujo de salida.

Alcino Dall Igna Junior
fuente
2
en.cppreference.com/w/cpp/io/basic_ostream/flush flush se sincroniza con el dispositivo de almacenamiento con el que está asociado. Esta no es la misma reinicialización.
Más claro el
-12

Estos no descartan los datos en el flujo de cadena en gnu c ++

    m.str("");
    m.str() = "";
    m.str(std::string());

Lo siguiente sí vacía el flujo de cadena para mí:

    m.str().clear();
Juan
fuente
77
No estoy tan seguro de que esto funcione, debido a las mismas razones por las que bernhardrusch no funcionaría. La función .str () devuelve una copia, y borrar la copia no haría nada.
Verdagon
1
Esta solución NO funciona para Microsoft Visual C ++.
Zak
Incorrecto. Clear estaría operando en la cadena devuelta de la secuencia, no en la secuencia misma.
Joey Carson