9

I wanted to experiment with stringstream for an assignment, but I'm a little confused on how it works. I did a quick search but couldn't find anything that would answer my question.

Say I have a stream with a dynamic size, how would I know when to stop writing to the variable?

 string var = "2 ++ asdf 3 * c";
 stringstream ss;

 ss << var;

 while(ss){
  ss >> var;
  cout << var << endl;
 }

and my output would be:

2  
++  
asdf  
3  
*  
c  
c  

I'm not sure why I get that extra 'c' at the end, especially since _M_in_cur = 0x1001000d7 ""

James McNellis
  • 348,265
  • 75
  • 913
  • 977
thomast.sang
  • 181
  • 1
  • 2
  • 4
  • The fact that it's a stringstream doesn't change much of anything -- you read from it like you would any other stream. – Jerry Coffin Sep 21 '10 at 03:31

3 Answers3

23

You get the extra c at the end because you don't test whether the stream is still good after you perform the extraction:

while (ss)        // test if stream is good
{
    ss >> var;    // attempt extraction          <-- the stream state is set here
    cout << var;  // use result of extraction
}

You need to test the stream state between when you perform the extraction and when you use the result. Typically this is done by performing the extraction in the loop condition:

while (ss >> var) // attempt extraction then test if stream is good
{
    cout << var;  // use result of extraction
}
James McNellis
  • 348,265
  • 75
  • 913
  • 977
0

The while(ss) condition check in your code checks if the last read from the stream was successful or not. However, this check is going to return true even when you have read the last word in your string. Only the next extraction of ss >> var in your code is going to make this condition false since the end of the stream has been reached & there is nothing to extract into the variable var. This is the reason you get an extra 'c' at the end. You can eliminate this by changing your code as suggested by James McNellis.

naivnomore
  • 1,291
  • 8
  • 14
-2

There is also a member function good() which tests if the stream can be used for I/O operations. So using this the above code can be changed into

while(ss.good())  // check if the stream can be used for io
{
    ss >> var;    // attempt extraction          <-- the stream state is set here
    cout << var;  // use result of extraction
}
Werner Henze
  • 16,404
  • 12
  • 44
  • 69
Manoj R
  • 3,197
  • 1
  • 21
  • 36
  • 1
    This is still incorrect in the general case: if you are trying to extract an `int` and the next available characters in the buffer can't be read as an `int`, the extraction will fail. – James McNellis Sep 21 '10 at 14:13