简体   繁体   中英

Setting the content of a std::stringstream with str(const char*) has strange consequences

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? Ei 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.

The default open mode for a std::stringstream object is in | out 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);

Live Demo

Alternatively, use an std::ostringstream , which initializes the internal std::stringbuf subobject with out | mode out | mode .

std::ostringstream("Setting string", std::ios_base::ate);

Live Demo

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM