istringstream question

Hello,

I have a question :)

1
2
3
4
5
6
7
istringstream line("Hello ");
string s;
while(line.good())
{
line >> s;
cout << "s is " << s << endl;
}


Why does it print two times the word Hello? The >> operator should stop at the frist space but then at next iteration it's like it starts again from the beginning. Can you help me please?

Thank you very much
After you read the 1st from 'line', is is still good so try moving the condition after getting input:
1
2
3
4
5
6
while(true)
{
    line >> s;
    if (!line.good()) break;
    cout << "s is " << s << endl;
}
That works but if line is "Hello message", then message is never shown because after reading the next word line is not good.
it's still good while reading to the end, it goes bad after trying to read after the end
Thank tou for your answer but if I try to run the following program:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#include <stdio.h>
#include <iostream>
#include <sstream>

using namespace std;

int main(int argc, char *argv[])
{
        string s;
        istringstream cmd_line("Hello message");
        while(true) {
                cmd_line >> s;
                if(!cmd_line.good()) break;
                cout << "s is " << s << endl;
        }
        return 0;
}


output is:
s is Hello
Last edited on
It is because you should be checking on the fail() condition.
Try this to see what is happening:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
#include <iomanip>
#include <iostream>
#include <sstream>

using namespace std;

int main()
  {
  string s;
  istringstream ss( "one two three four" );

  cout << "message-------- good()- bad()-- eof()-- fail()-\n"
       << left;

  do
    {
    s  = "(failed)";
    ss >> s;
    cout << " "
         << setw( 16 ) << s
         << setw(  8 ) << ss.good()
         << setw(  8 ) << ss.bad()
         << setw(  8 ) << ss.eof()
         << setw(  8 ) << ss.fail()
         << endl;
    }
  while (ss);

  return 0;
  }

Try changing things here and there to see how it affects the flags. For example, you can try commenting-out line 17, or putting spaces at the end of the string on line 10.

Hope this helps.
closed account (z05DSL3A)
One of the issuses with Bazzy's code,
1
2
3
4
5
6
while(true)
{
    line >> s;
    if (!line.good()) break;
    cout << "s is " << s << endl;
}
is that when line becomes not good, it beaks out of the loop and thus does not go on to the cout.


You cold swap line 3 and 4
1
2
3
4
5
6
while(true)
{
    if (!line.good()) break;    
    line >> s;   
    cout << "s is " << s << endl;
}

but you would still have a problem with whitspaces (if any) at the end of the stream.

You could do somthing like:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
    istringstream line(" Hello \t message \n hello message ");
 
    if(line.good())
    {
        string str;
        int index =0;
        do
        {
            str.clear();
            line >> str;
            if(str.empty()) continue;

            cout << ++index << " str: " << str << endl;

        }while(line.good());
    }


Thank you! That helped me. I check fail() after >> operator ;)
Topic archived. No new replies allowed.