ostringstream clear

K

Kyle Kolander

I posted this in response to a previous thread but have not gotten any
replies back... Hopefully someone has an answer?

From looking at sections 27.7.3.2 and 27.7.1.2 of the standard, it appears
str("") does not clear the stream bits. It seems to me that in clearing the
internal buffer, one would intend that the stream bits would also be reset
(in a good state). Is there a reason this is not the defined behavior?
Aside from a slight performance hit, I have not been able to think of a
situation where it would be beneficial to set the internal buffer to an
empty string (in essence resetting it), but leave the state of the stream
unchanged. If performance is the reason, then under what conditions will an
ostringstream enter a "bad" state (needing to be clear()'ed)?

If I'm just doing stuff like this, is there ever a need to clear():

// contrived example
ostringstream oss;
for (int i = 0; i < 50; ++i)
{
oss << "File:" << i;
cout << oss.str() << endl;
oss.str("");
}

Thanks,
Kyle
 
S

Steven T. Hatton

Kyle said:
I posted this in response to a previous thread but have not gotten any
replies back... Hopefully someone has an answer?

From looking at sections 27.7.3.2 and 27.7.1.2 of the standard, it
appears
str("") does not clear the stream bits. It seems to me that in clearing
the internal buffer, one would intend that the stream bits would also be
reset
(in a good state). Is there a reason this is not the defined behavior?
Aside from a slight performance hit, I have not been able to think of a
situation where it would be beneficial to set the internal buffer to an
empty string (in essence resetting it), but leave the state of the stream
unchanged. If performance is the reason, then under what conditions will
an ostringstream enter a "bad" state (needing to be clear()'ed)?

stringstream is a wonderful concept with some less than ideal design
features. I tried to get the default behavior of stringstream ss("default
text"); defined such that the write pointer is position at the end of the
content. I had assumed it was an oversite on the part of the Standard
Committee, as it turns out, it was a conscious design feature. I was
pointed to some email in which Stroustrup strongly encouraged specifying
the behavior I expected, but it would seem he did not persuade others of
the wisdome of doing so.

There may actually be a modestly persuasive argument for the feature you've
discovered. Someone might argue that it makes more sense to check the
state of the stream after calling oss.str("");
If I'm just doing stuff like this, is there ever a need to clear():

// contrived example
ostringstream oss;
for (int i = 0; i < 50; ++i)
{
oss << "File:" << i;
cout << oss.str() << endl;
oss.str("");
}

I really can't think of what would put ostringstream into a bad state, but
if you are going to be clear()ing it, you should probably be checking for
errors as well. I don't know what would happen if you tried to force
something that was a data type that it didn't understand into the pipe.
I'm not even sure how you could accomplish that with strong type checking.
 
K

Kyle Kolander

Steven said:
Kyle Kolander wrote:




stringstream is a wonderful concept with some less than ideal design
features. I tried to get the default behavior of stringstream ss("default
text"); defined such that the write pointer is position at the end of the
content. I had assumed it was an oversite on the part of the Standard
Committee, as it turns out, it was a conscious design feature. I was
pointed to some email in which Stroustrup strongly encouraged specifying
the behavior I expected, but it would seem he did not persuade others of
the wisdome of doing so.


I'm curious, what was the reason given for this design feature? Is
there a constructor that allows you to set the write pointer to the
"end" of the used portion of the internal buffer? (Sorry, all of my
references are at work) I'll admit I have really only used the
stringstreams as either input or output exclusively. Just for
clarification:

ostringstream ostr("My name is ");
ostr << "Kyle.";
cout << ostr.str();

What does the standard say should be the result of this output? If I
understand you correctly, are you saying it should be "Kyle.me is "
according to the standard? I would expect "My name is Kyle.".

There may actually be a modestly persuasive argument for the feature you've
discovered. Someone might argue that it makes more sense to check the
state of the stream after calling oss.str("");


Why? If you wanted to be extra careful checking for errors, it seems
like a two step process:
1.) Attempt an operation on the stream.
2.) Query the stream for a bad state.

I don't see how the str("") would be the operation to put the stream
into a bad state? Why check it at this point? I'm not sure about this,
but would the str("") even succeed if the stream was already in a bad
state, i.e. would the internal buffer be deallocated and set to an empty
string?

I really can't think of what would put ostringstream into a bad state, but
if you are going to be clear()ing it, you should probably be checking for
errors as well. I don't know what would happen if you tried to force
something that was a data type that it didn't understand into the pipe.
I'm not even sure how you could accomplish that with strong type checking.


That is exactly what I was thinking. So if anyone has an example,
please share. Thanks!

As far as the call to clear(), in the previous thread where I originally
posted this question, someone basically said that it was not enough to
just call str(""), but that it had to be accompanied with a call to
clear(). That is what got me thinking about why str("") would not
guarantee that the stream is in a good state....

Thanks for your reply,
Kyle
 
S

Steven T. Hatton

Kyle said:
Steven T. Hatton wrote:


I'm curious, what was the reason given for this design feature?
Reason is an interesting word in this context. I will say there was an
argument presented. There may actually be a _reason_, but I am unaware of
it. The argument is that the std::stringstream defined as it is follows
the same semantics as std::fstream. I tried to find an example of why I
would want this behavior, but I didn't find any satisfying examples. The
best I can come up with on my own is that I might use std::stringstream as
the backing of an edit buffer. With the current design, the insert point
would be set at the beginning of the "file" if it were initialized by
passing a string.
Is
there a constructor that allows you to set the write pointer to the
"end" of the used portion of the internal buffer? (Sorry, all of my
references are at work)
I'll admit I have really only used the
stringstreams as either input or output exclusively. Just for
clarification:

ostringstream ostr("My name is ");
ostr << "Kyle.";
cout << ostr.str();

What does the standard say should be the result of this output? If I
understand you correctly, are you saying it should be "Kyle.me is "
according to the standard? I would expect "My name is Kyle.".

I'm only a page ahead of you on this. I've only read about it, and used it
for a few toy programs sofar. (and one little micro app). Try the
following as-is. and then remove the 'o' in std::eek:stringstream, and see
what happens.

#include <iostream>
#include <iomanip>
#include <string>
#include <sstream>


std::string str1() {
std::stringstream s;
s <<""
"Whoever limiting his worldly ambitions finds satisfaction in the
speculative\n"
"life has in the approval of an enlightened and competent judge a
powerful\n"
"incentive to labours, the benefits of which are great but remote,
and\n"
"therefore such as the vulgar altogether fail to recognise.\n"
"To such a judge and to his gracious attention I now dedicate this work,
and\n"
"to his"
<< std::endl;
return s.str();
}

std::string str2() {
std::stringstream s;
s <<"What is mind? No Matter. What is matter? Never mind."<< std::endl;
return s.str();
}


int main() {

std::stringstream s(str1());
s << str2();
std::cout << s.str() << std::endl;

std::eek:stringstream ss(str1(), std::ios_base::app);
ss << str2();
std::cerr << std::boolalpha << ss.fail() << std::endl;
std::cout << ss.str() << std::endl;
}

This is the output I get from the version shown:

What is mind? No Matter. What is matter? Never mind.
tion in the speculative
life has in the approval of an enlightened and competent judge a powerful
incentive to labours, the benefits of which are great but remote, and
therefore such as the vulgar altogether fail to recognise.
To such a judge and to his gracious attention I now dedicate this work, and
to his

false
Whoever limiting his worldly ambitions finds satisfaction in the speculative
life has in the approval of an enlightened and competent judge a powerful
incentive to labours, the benefits of which are great but remote, and
therefore such as the vulgar altogether fail to recognise.
To such a judge and to his gracious attention I now dedicate this work, and
to his
What is mind? No Matter. What is matter? Never mind.
Why? If you wanted to be extra careful checking for errors, it seems
like a two step process:
1.) Attempt an operation on the stream.
2.) Query the stream for a bad state.

I don't see how the str("") would be the operation to put the stream
into a bad state? Why check it at this point? I'm not sure about this,
but would the str("") even succeed if the stream was already in a bad
state, i.e. would the internal buffer be deallocated and set to an empty
string?

I hadn't expressed myself well. I mean that ther may be situation where
that would be the desierable thing. For example, if the user didn't know
exactly what was passed to str(). That operation might take place at a
point where checking the error is not convenent. IOW, the operation it it
clear()ed would be implicitly destroying state information whether that's
what the user wants or not. str(""); is just another call to set the value
of the string. It's only special because it happens to put the string into
a commonly desired state. It might just as easily happen arbitrarily. For
example if the string passed represented an empty line of text.
That is exactly what I was thinking. So if anyone has an example,
please share. Thanks!

As far as the call to clear(), in the previous thread where I originally
posted this question, someone basically said that it was not enough to
just call str(""), but that it had to be accompanied with a call to
clear(). That is what got me thinking about why str("") would not
guarantee that the stream is in a good state....

Thanks for your reply,
Kyle
Run the code I posted with, and without the 'o', and see if it doesn't get
you back to wondering.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Similar Threads


Members online

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,580
Members
45,055
Latest member
SlimSparkKetoACVReview

Latest Threads

Top