I'd like to clear out and reuse an ostringstream (and the underlying buffer) so that my app doesn't have to do as many allocations. How do I reset the object to its initial state?
-
possible duplicate of [In C++, how do you clear a stringstream variable?](http://stackoverflow.com/questions/20731/in-c-how-do-you-clear-a-stringstream-variable) – mpromonet Oct 19 '14 at 13:36
4 Answers
I've used a sequence of clear and str in the past:
// clear, because eof or other bits may be still set.
s.clear();
s.str("");
Which has done the thing for both input and output stringstreams. Alternatively, you can manually clear, then seek the appropriate sequence to the begin:
s.clear();
s.seekp(0); // for outputs: seek put ptr to start
s.seekg(0); // for inputs: seek get ptr to start
That will prevent some reallocations done by str
by overwriting whatever is in the output buffer currently instead. Results are like this:
std::ostringstream s;
s << "hello";
s.seekp(0);
s << "b";
assert(s.str() == "bello");
If you want to use the string for c-functions, you can use std::ends
, putting a terminating null like this:
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
is a relict of the deprecated std::strstream
, which was able to write directly to a char array you allocated on the stack. You had to insert a terminating null manually. However, std::ends
is not deprecated, i think because it's still useful as in the above cases.

- 496,577
- 130
- 894
- 1,212
-
I am trying to use s.str() with an ostream. The size is messing it up (i can see the first character is null but it prints much more). Is there a good way to fix the str length? i am using s.str().c_str(); ATM and it works nicely – Jun 06 '11 at 16:09
-
Actually even this isnt correct. I just did `s.str("");` instead. `auto str = s.str(); auto cstr = str.c_str(); file << cstr; s.clear(); s.seekp(0); s << ends;` – Jun 06 '11 at 16:20
-
the std::ends doesn't work for me in google test `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>"` and if I reuse with different length strings I get left over bits – David van Laatum Jun 27 '17 at 07:48
-
1The Alternative is the true answer if you want to avoid reallocation. And if you want to truly "start fresh" without reallocation just call seekp(0) again after sending std::end. `s.seekp(0); s << std::ends; s.seekp(0);` – Chip Grandits Jun 30 '17 at 17:35
Seems to be that the ostr.str("")
call does the trick.

- 28,636
- 4
- 59
- 87
-
11Worth pointing out that this won't re-use the underlying buffer from the ostringstream - it just assigns a new buffer. So while you're reusing the ostringstream object, you're still allocating two buffers. I don't think ostringstream is designed for reuse in the manner you intend. – razlebe Mar 08 '09 at 21:09
-
2It also doesn't clear out the state, which is what .clear() does. I agree, it really isn't meant to be used like this. Just create a new one to be sure. Only if you profile will you find out if it makes any difference. – Brian Neal Mar 09 '09 at 02:30
-
1sgreeve, Brian, that's right. Note, however, how the litb's method above requires of the usage of std::ends. It reuses the buffer, but makes you code differently as usual with stringstreams (normally you don't use std::ends). – Diego Sevilla Mar 09 '09 at 08:21
If you're going to clear the buffer in a way that will cause it to be cleared before it's first use, you'll need to add something to the buffer first 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
}
};

- 11,326
- 43
- 62
- 91

- 126
- 1
- 3
-
I'm not seeing the failing behavior on VS2012. Furthermore, calling [`clear`](http://www.cplusplus.com/reference/ios/ios/clear/) will _cause_ the `failbit` to be set if the stream is empty. While just calling [`seekp`](http://www.cplusplus.com/reference/ostream/ostream/seekp/) should simply return if no stream exists. – Jonathan Mee Jul 08 '14 at 11:42
You don't. Use two differently named streams for clarity and let the optimizing compiler figure out that it can reuse the old one.

- 7,423
- 33
- 35

- 965
- 2
- 13
- 26
-
5consider the use case where the code is looping over input data, writing to an `ostringstream` (based on the data read) and then has to write the string built in the `ostringstream` somewhere from time to time (e.g. after a certain character sequence was read) and start building a new string. – Andre Holzner Jan 31 '12 at 15:09