599 Stimmen

Wie löscht man eine stringstream Variable?

Ich habe bereits mehrere Dinge versucht,

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

beide funktionieren nicht.

16voto

Francisco Cortes Punkte 990

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 iterativ gemäß der Anforderung eines Benutzers ausgeführt wurde, eine stringstream-Variable füllen würde. Diese würde beim ersten Mal, wenn der Code ausgeführt wurde, gut funktionieren, aber die stringstream-Variable beim nächsten Mal nicht leeren, wenn der Benutzer denselben Code erneut ausführen würde. Aber die beiden Codezeilen unten haben schließlich die stringstream-Variable jedes Mal geleert, bevor sie die String-Variable füllen. (2 Stunden ausprobieren und googeln), übrigens würde das Verwenden jeder Zeile für sich allein nicht funktionieren.

// die stringstream-Variable leeren

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

// die stringstream-Variable füllen
sstm << "Müll" << "MehrMüll";

4voto

Es gibt viele andere Antworten, die "funktionieren", aber sie machen oft unnötige Kopien oder allozieren Speicher neu.

  1. Das Austauschen von Streams bedeutet, dass einer von ihnen verworfen werden muss, was die Speicherzuweisung verschwendet. Das gilt auch für die Zuweisung eines standardmäßig konstruierten Streams,

  2. Das Zuweisen an den String im String-Puffer (über stringstream::str oder stringbuf::str) kann den bereits vom String allokierten Puffer verlieren.

Der kanonische Weg, den String-Stream zu leeren, wäre:

void clear(std::stringstream &stream)
{
   if (stream.rdbuf()) stream.rdbuf()->pubseekpos(0);
}

Der kanonische Weg, die Größe der Daten im Puffer des Streams zu erhalten, ist:

std::size_t availSize() (const std::stringstream& stream)
{
   if (stream.rdbuf())
      return std::size_t(
         stream.rdbuf()->pubseekoff(0, std::ios_base::cur, std::ios_base::out));
   else
      return 0;
}

Der kanonische Weg, die Daten aus dem Stream in einen anderen vorallokierten Puffer zu kopieren und dann zu löschen, wäre dann:

std::size_t readAndClear(std::stringstream &stream, void* outBuf, std::size_t outSize)
{
   auto const copySize = std::min(availSize(stream), outSize);
   if (!copySize) return 0; // kümmert sich um null stream.rdbuf()

   stream.rdbuf()->sgetn(outBuf, copySize);
   stream.rdbuf()->pubseekpos(0); // Puffer leeren

   return copySize;
}

Ich beabsichtige, dass dies eine kanonische Antwort ist. Rechtsanwälte der Sprache, fühlt euch frei, mit anzupacken.

4 Stimmen

Ich habe diese Antwort hochgevotet, aber dann festgestellt, dass sie die aktuelle Größe tatsächlich nicht auf null setzt, sodass der alte Inhalt immer noch sichtbar ist: godbolt.org/z/erP8dMcfK

-1voto

Es ist ein konzeptuelles Problem.

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

3 Stimmen

de.cppreference.com/w/cpp/io/basic_ostream/flush flush synchronisiert mit dem Datenspeichergerät, mit dem es verbunden ist. Dies ist nicht die gleiche Neuinitalisierung.

-14voto

John Punkte 13

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

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

Das Folgende leert den stringstream für mich:

    m.str().clear();

7 Stimmen

Ich bin mir nicht sicher, ob das funktionieren würde, weil aus denselben Gründen wie bei bernhardrusch's es nicht funktionieren würde. Die .str() Funktion gibt eine Kopie zurück, und das Löschen der Kopie würde nichts ausrichten.

1 Stimmen

Diese Lösung funktioniert NICHT für Microsoft Visual C++.

0 Stimmen

Falsch. Richtig wäre die Ausführung auf dem aus dem Stream zurückgegebenen String, nicht auf dem Stream selbst.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X