Ich möchte einen Ostringstream (und den zugrunde liegenden Puffer) löschen und wiederverwenden, damit meine App nicht so viele Zuordnungen vornehmen muss. Wie setze ich das Objekt in den Ausgangszustand zurück?
Ich möchte einen Ostringstream (und den zugrunde liegenden Puffer) löschen und wiederverwenden, damit meine App nicht so viele Zuordnungen vornehmen muss. Wie setze ich das Objekt in den Ausgangszustand zurück?
Antworten:
Ich habe in der Vergangenheit eine Folge von clear und str verwendet:
// clear, because eof or other bits may be still set.
s.clear();
s.str("");
Was sowohl für Input- als auch für Output-Stringstreams funktioniert hat. Alternativ können Sie manuell löschen und dann zu Beginn die entsprechende Reihenfolge suchen:
s.clear();
s.seekp(0); // for outputs: seek put ptr to start
s.seekg(0); // for inputs: seek get ptr to start
Dies verhindert einige Neuzuweisungen, indem str
stattdessen alles überschrieben wird, was sich derzeit im Ausgabepuffer befindet. Die Ergebnisse sind wie folgt:
std::ostringstream s;
s << "hello";
s.seekp(0);
s << "b";
assert(s.str() == "bello");
Wenn Sie die Zeichenfolge für c-Funktionen verwenden möchten, können Sie std::ends
eine abschließende Null wie folgt setzen:
std::ostringstream s;
s << "hello";
s.seekp(0);
s << "b" << std::ends;
assert(s.str().size() == 5 && std::strlen(s.str().data()) == 1);
std::ends
ist ein Relikt des Veralteten std::strstream
, das direkt in ein Char-Array schreiben konnte, das Sie auf dem Stapel zugewiesen haben. Sie mussten manuell eine abschließende Null einfügen. Allerdings std::ends
ist nicht veraltet, denke ich, weil es immer noch nützlich ist, wie in den oben genannten Fällen.
s.str("");
stattdessen einfach getan . auto str = s.str(); auto cstr = str.c_str(); file << cstr; s.clear(); s.seekp(0); s << ends;
boost::any a = 1; std::ostringstream buffer; buffer << a << std::ends; EXPECT_EQ( buffer.str(), "any<(int)1>" );
TestUtilsTest.cpp:27: Failure Expected: buffer.str() Which is: "any<(int)1>\0" To be equal to: "any<(int)1>"
und wenn ich mit Strings unterschiedlicher Länge wiederverwenden, bleiben mir Bits übrig
s.seekp(0); s << std::ends; s.seekp(0);
Scheint, dass der ostr.str("")
Anruf den Trick macht.
Wenn Sie den Puffer so löschen möchten, dass er vor seiner ersten Verwendung gelöscht wird, müssen Sie dem Puffer zuerst mit MSVC etwas hinzufügen.
struct Foo {
std::ostringstream d_str;
Foo() {
d_str << std::ends; // Add this
}
void StrFunc(const char *);
template<class T>
inline void StrIt(const T &value) {
d_str.clear();
d_str.seekp(0); // Or else you'll get an error with this seek
d_str << value << std::ends;
StrFunc(d_str.str().c_str()); // And your string will be empty
}
};
clear
wird dazu führen , die failbit
gesetzt werden , wenn der Strom ist leer. Während nur anrufen seekp
sollte einfach zurückkehren, wenn kein Stream existiert.
Das tust du nicht. Verwenden Sie aus Gründen der Übersichtlichkeit zwei Streams mit unterschiedlichen Namen und lassen Sie den optimierenden Compiler herausfinden, dass er den alten wiederverwenden kann.
ostringstream
(basierend auf den gelesenen Daten) schreibt und dann ostringstream
von Zeit zu Zeit (z. B. nachdem eine bestimmte Zeichenfolge gelesen wurde) die eingebaute Zeichenfolge irgendwo schreibt und startet Erstellen einer neuen Zeichenfolge.