Vorrei eliminare e riutilizzare un ostringstream (e il buffer sottostante) in modo che la mia app non debba fare tante assegnazioni. Come faccio a ripristinare l'oggetto al suo stato iniziale?Come riutilizzare un ostringstream?
risposta
Ho usato una sequenza di chiaro e str in passato:
// clear, because eof or other bits may be still set.
s.clear();
s.str("");
che ha fatto la cosa giusta per entrambi stringstreams ingresso e di uscita. In alternativa, è possibile cancellare manualmente, poi cercare la sequenza appropriata per l'inizio:
s.clear();
s.seekp(0); // for outputs: seek put ptr to start
s.seekg(0); // for inputs: seek get ptr to start
che impedirà alcune riassegnazioni effettuate da str
sovrascrivendo tutto ciò che è nel buffer di output attualmente invece. I risultati sono in questo modo:
std::ostringstream s;
s << "hello";
s.seekp(0);
s << "b";
assert(s.str() == "bello");
Se si desidera utilizzare la stringa per C-funzioni, è possibile utilizzare std::ends
, mettendo un nullo di terminazione come questo:
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
è un relitto del deprecato std::strstream
, che è stato in grado di scrivere direttamente su un array di caratteri che è stato assegnato nello stack. Dovevi inserire un null che termina manualmente. Tuttavia, std::ends
non è deprecato, penso perché è ancora utile come nei casi precedenti.
Sto cercando di usare s.str() con un ostream. La dimensione è un pasticcio (posso vedere il primo carattere è nullo ma stampa molto di più). C'è un buon modo per risolvere la str str? sto usando s.str(). c_str(); ATM e funziona bene –
In realtà anche questo non è corretto. Ho appena fatto 's.str (" ");' invece. 'auto str = s.str(); auto cstr = str.c_str(); file << cstr; s.clear(); S.seekp (0); s << ends; ' –
std :: ends non funziona per me nel google test ' boost :: any a = 1; std :: buffer di ostringstream; buffer << a << std :: ends; EXPECT_EQ (buffer.str(), "qualsiasi <(int)1>"); '' TestUtilsTest.cpp: 27: Guasto atteso: buffer.str() Quale è: "qualsiasi <(int)1> \ 0" essere pari a: "qualsiasi " e se riutilizzo con stringhe di lunghezza diversa, rimango sui bit –
Sembra che sia la chiamata ostr.str("")
a fare il trucco.
Vale la pena sottolineare che questo non riutilizzerà il buffer sottostante dal ostringstream - assegna solo un nuovo buffer. Quindi mentre riutilizzi l'oggetto ostringstream, stai ancora assegnando due buffer. Non penso che lo stringstream sia progettato per essere riutilizzato nel modo che tu intendi. – razlebe
Inoltre non cancella lo stato, che è ciò che fa .clear(). Sono d'accordo, non è pensato per essere usato in questo modo. Basta crearne uno nuovo per essere sicuro. Solo se il tuo profilo scoprirai se fa alcuna differenza. –
sgreeve, Brian, giusto. Si noti, tuttavia, come il metodo di litb sopra richiede l'uso di std :: ends. Riusa il buffer, ma rende il codice in modo diverso come al solito con gli stringstreams (normalmente non si usa std :: ends). –
Non è così. Usate due stream con nomi diversi per chiarezza e lasciate che il compilatore ottimizzante capisca che può riutilizzare quello vecchio.
... e naturalmente spero che lo faccia, capirlo. –
consideriamo il caso d'uso in cui il codice sta eseguendo il looping sui dati di input, scrivendo su un 'stringstream' (basato sulla lettura dei dati) e quindi deve scrivere la stringa incorporata nel' stringstream' di tanto in tanto (ad esempio dopo un certo la sequenza di caratteri è stata letta) e inizia a creare una nuova stringa. –
Se si desidera cancellare il buffer in un modo che causerà la cancellazione prima del primo utilizzo, sarà necessario aggiungere qualcosa al buffer w/MSVC.
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
}
};
Non vedo il comportamento anomalo su VS2012. Inoltre, chiamando ['clear'] (http://www.cplusplus.com/reference/ios/ios/clear/) verrà _cause_ il' failbit' da impostare se lo stream è vuoto. Mentre solo chiamare ['seekp'] (http://www.cplusplus.com/reference/ostream/ostream/seekp/) dovrebbe semplicemente tornare se non esiste alcun flusso. –
possibile duplicato del [In C++, come si fa a cancellare una variabile stringstream?] (Http://stackoverflow.com/questions/20731/in-c-how-do-you-clear-a-stringstream -variabile) – mpromonet