Wie löscht man eine Stringstream-Variable?

486

Ich habe schon mehrere Dinge ausprobiert,

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

beide funktionieren nicht.

Codierung ohne Kommentare
quelle

Antworten:

771

Für alle Standardbibliothekstypen ist die Mitgliedsfunktion empty()eine Abfrage, kein Befehl, dh sie bedeutet "Sind Sie leer?" nicht "Bitte werfen Sie Ihren Inhalt weg".

Die clear()Member-Funktion wird von geerbt iosund zum Löschen des Fehlerstatus des Streams verwendet. Wenn beispielsweise für einen Dateistream der Fehlerstatus auf eofbit(Dateiende) festgelegt ist, wird durch Aufrufen clear()der Fehlerstatus auf goodbit(kein Fehler) zurückgesetzt. .

Zum Löschen des Inhalts von a stringstreamverwenden Sie:

m.str("");

ist richtig, obwohl mit:

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

ist technisch effizienter, da Sie das Aufrufen des erforderlichen std::stringKonstruktors vermeiden const char*. Aber heutzutage sollte jeder Compiler in beiden Fällen den gleichen Code generieren können - also würde ich einfach alles verwenden, was besser lesbar ist.

Wilka
quelle
105
Folgendes passiert, wenn Sie den Teil "clear ()" vergessen. stackoverflow.com/q/2848087/635549
Galath
8
@KshitijBanerjee Ich denke in C ++ sind m.str () und m.str ("") zwei verschiedene Funktionen. m.str () ruft eine Funktion auf, die keinen Parameter erwartet hat, während m.str ("") die Funktion aufruft, die einen const char * -Parameter akzeptiert. m.str () wurde möglicherweise als get- Funktion implementiert , die den String zurückgibt, während m.str ("") möglicherweise als set- Funktion implementiert wurde .
Dinesh PR
4
Wie Galath sagte, ist es sehr wichtig, auch m.clear () hinzuzufügen; zusätzlich zu m.str ("");. Andernfalls können Probleme auftreten, wenn Sie den Stringstream irgendwann mit einem leeren String füllen.
Sputnik
1
@anthropod Ja das war letztes Jahr. Ich habe es seitdem zum Laufen gebracht.
James
1
Oh Mann, ist das intuitiv. Genau wie alles andere in C ++!
sonniger Mond
47

Sie können den Fehlerstatus löschen und den Stringstream in einer Zeile leeren

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

Dadurch wird m effektiv auf einen standardmäßig erstellten Zustand zurückgesetzt

Nikos Athanasiou
quelle
3
Dies ist die effizienteste und eleganteste Methode im Vergleich zu allen anderen Antworten hier. Std :: stringstream :: swap ist jedoch eine C ++ 11-Funktion, und diese Lösung funktioniert nicht für frühere C ++ 11-Compiler.
101010
4
Funktion fehlt noch in GNU g ++ v4.8, siehe stackoverflow.com/questions/24429441/…
Joachim W
7
@ 101010: Wie ist das Tauschen besser als das Verschieben?
Deduplikator
2
@AsetD: Auch wenn es keine Ausnahme ist, haben Sie die standardmäßig erstellte temporäre Version vergessen?
Deduplikator
3
Dies ist wenig effizient. Wenn ich original ss wieder verwenden möchte. Es tauscht eine leere für mich.
Zhang
36
m.str("");

scheint zu funktionieren.

Codierung ohne Kommentare
quelle
3
Dies würde durch .clear () gelöscht, das im OP angegeben ist.
Dave Lugg
33

Dies sollte unabhängig vom Compiler der zuverlässigste Weg sein:

m=std::stringstream();
Jerron
quelle
2
Dies ist meiner Meinung nach besser, weil m.str (""); Mein Stringstream blieb bei diesem leeren Wert hängen, was auch immer ich versuchte. Aber damit habe ich dieses Problem nicht
Gelatine1
3
Ich bin auf das gleiche Problem gestoßen, für mich mm.clear(); mm.str("");hat es den Trick getan. (kein C ++ 11, sonst wäre Swap besser).
hochl
1
@hochl: Warum wäre swapbesser als Umzugszuweisung ?
Deduplikator
4
Es ist nicht für alle Situationen gut. Dies würde den Puffer jedes Mal neu zuweisen, während mm.str ("") dies nicht tun würde.
Shital Shah
3
Mein primärer Anwendungsfall für das Leeren eines Stringstream-Objekts besteht darin, ein threadlokales Stringstream-Objekt zu behalten, um eine unnötige Instanziierung des Stringstreams zu verhindern - das Instanziieren eines neuen Stringstream-Objekts kopiert das globale Gebietsschemaobjekt - theoretisch ist dies schnell und beinhaltet nur das Inkrementieren eines Atoms, aber Auf der Ebene der Parallelität, mit der ich zu tun habe, ist es oft lähmend.
Spacemoose
12

Ich bin immer dabei:

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

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

{
    std::stringstream ss;
    ss << "heck";
}
TimoK
quelle
1
Ist das besser als das Löschen derstringstream?
Robur_131
11

meine 2 Cent:

Dies schien für mich in xcode und dev-c ++ zu funktionieren. Ich hatte ein Programm in Form eines Menüs, das, wenn es gemäß der Anforderung eines Benutzers iterativ ausgeführt wird, eine Stringstream-Variable ausfüllt, die beim ersten Mal in Ordnung ist run, würde aber den Stringstream nicht löschen, wenn der Benutzer das nächste Mal denselben Code ausführt. Die beiden folgenden Codezeilen haben die Stringstream-Variable jedoch jedes Mal gelöscht, bevor die String-Variable aufgefüllt wurde. (2 Stunden Versuch und Irrtum und Google-Suche), übrigens, jede Zeile für sich zu verwenden, würde den Trick nicht tun.

//clear the stringstream variable

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

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

Es ist ein konzeptionelles Problem.

Stringstream ist ein Stream, daher sind seine Iteratoren vorwärts und können nicht zurückkehren. In einem Ausgabe-Stringstream benötigen Sie ein Flush (), um ihn wie in jedem anderen Ausgabestream neu zu initialisieren.

Alcino Dall Igna Junior
quelle
2
en.cppreference.com/w/cpp/io/basic_ostream/flush flush wird mit dem Speichergerät synchronisiert, dem es zugeordnet ist. Dies ist nicht die gleiche Neuinitialisierung.
Klarer
-12

Diese verwerfen die Daten im Stringstream in gnu c ++ nicht

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

Folgendes leert den Stringstream für mich:

    m.str().clear();
John
quelle
7
Ich bin mir nicht sicher, ob das funktionieren würde, aus den gleichen Gründen, aus denen Bernharduschus nicht funktionieren würde. Die Funktion .str () gibt eine Kopie zurück, und das Löschen der Kopie würde nichts bewirken.
Verdagon
1
Diese Lösung funktioniert NICHT für Microsoft Visual C ++.
Zak
Falsch. Clear würde mit der vom Stream zurückgegebenen Zeichenfolge arbeiten, nicht mit dem Stream selbst.
Joey Carson