Reputation: 854
I use std::stringstream
extensively to generate code. I have run into some querious behavior when setting the content with the str()
function followed by using the operator<<
. Can someone explain this behavior to me. I would very much appreciate it - Thanks.
Example One:
std::stringstream ssa;
ssa.str("Setting string");
std::cout << ssa.str() << std::endl;
ssa << " adding to string";
std::cout << ssa.str() << std::endl;
Output:
Setting string
adding to string
Expected:
Setting string
Setting string adding to string
So after a bit of reading up on the documentation I found that I should set the open mode to ios_base::ate
:
std::stringstream ssb(std::ios_base::ate);
ssb.str("Setting string");
std::cout << ssb.str() << std::endl;
ssb << " adding to string";
std::cout << ssb.str() << std::endl;
Output:
Setting string
Setting string
Again (or now) I would expect:
Setting string
Setting string adding to string
Why am I getting the results I am, and how do I get the result I want? E.i. Being able to set the initial string
of a stringstream
and the append to that string
?
I am aware that I can just set the content to the empty string("")
and then only use the <<operator
. This is in fact the workaround I am using. I just don't understand the observed behavior. And the workaround makes my code more messy.
Upvotes: 20
Views: 5753
Reputation: 11018
You forgot to set flag mode: std::ios_base::out
.
This will work:
std::stringstream ssb(std::ios_base::out | std::ios_base::ate);
ssb.str("Setting string");
std::cout << ssb.str() << std::endl;
ssb << " adding to string";
std::cout << ssb.str() << std::endl;
Output:
Setting string
Setting string adding to string
Upvotes: 8
Reputation: 96835
The default open mode for a std::stringstream
object is in | out
. Using a different mode overrides these options. Since the stream cannot be written to, the insertion operator cannot be used to write to the stream. This is why str()
gives the same output twice.
You need to manually open the stream in output mode as well:
std::stringstream ssb("Setting string", std::ios_base::out | std::ios_base::ate);
Alternatively, use an std::ostringstream
, which initializes the internal std::stringbuf
subobject with out | mode
.
std::ostringstream("Setting string", std::ios_base::ate);
Upvotes: 12