Search code examples
c++stlresetostringstream

How to reuse an ostringstream?


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?


Solution

  • 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.