Відповіді:
У минулому я використовував послідовність clear і str:
// clear, because eof or other bits may be still set.
s.clear();
s.str("");
Це зробило справу як для вхідних, так і вихідних потокових потоків. Крім того, ви можете вручну очистити, а потім шукати відповідну послідовність для початку:
s.clear();
s.seekp(0); // for outputs: seek put ptr to start
s.seekg(0); // for inputs: seek get ptr to start
Це запобіжить деяким перерозподілам str
, перезаписуючи все, що знаходиться у вихідному буфері, замість цього. Результати такі:
std::ostringstream s;
s << "hello";
s.seekp(0);
s << "b";
assert(s.str() == "bello");
Якщо ви хочете використовувати рядок для c-функцій, ви можете використовувати std::ends
, поставивши закінчуючий null таким чином:
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
- це релікт застарілого std::strstream
, який зміг записати безпосередньо до масиву char, який ви виділили у стеку. Вам довелося вставити завершальну нуль вручну. Однак, std::ends
це не застаріло, я думаю, тому що це все ще корисно, як у вищенаведених випадках.
s.str("");
замість цього. 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>"
і якщо я повторно використовую рядки різної довжини, мені залишаються біти
s.seekp(0); s << std::ends; s.seekp(0);
Здається, що ostr.str("")
дзвінок виконує трюк.
Якщо ви збираєтеся очистити буфер таким чином, що він змусить його очистити до першого використання, вам потрібно буде додати щось до буфера спочатку 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
}
};
clear
буде викликати до failbit
встановлювати , якщо потік порожній. Хоча просто дзвінок seekp
повинен просто повернутися, якщо потоку немає.
Ви цього не робите. Використовуйте два по-різному названі потоки для ясності та дозвольте оптимізуючим компілятору зрозуміти, що він може повторно використовувати старий.
ostringstream
(на основі даних, що читаються), а потім повинен записувати рядок, побудований ostringstream
десь час від часу (наприклад, після того, як прочитана певна послідовність символів), і почати побудова нового рядка.