1

The following code:

int main() {
    stringstream ss;
    string str;
    str = "999:97 42:22 44:102300";
    ss << str;
    char ch;
    int temp, temp1;
    while (1) {
        if (ss.fail()) {
    break;
    }
    ss >> temp >> ch >> temp1;
    cout << temp << ":" << temp1 << endl;
    }
    return 0;
}

This gives the following output:

999:97
42:22
44:102300
44:102300

Here's a link as well: http://ideone.com/cC75Sk

I just wanted to know, why does the code doesn't end after the break statement ?

johnsyweb
  • 136,902
  • 23
  • 188
  • 247
Shivam Dixit
  • 318
  • 4
  • 13
  • You're using input without checking that the read succeeded. Get rid of the if and use the input statement as the condition. – chris Aug 17 '13 at 09:16
  • possible duplicate of [Testing stream.good() or !stream.eof() reads last line twice](http://stackoverflow.com/questions/4324441/testing-stream-good-or-stream-eof-reads-last-line-twice) – Blastfurnace Aug 17 '13 at 09:42

2 Answers2

2

You may modify your program like

int main() 
{
    stringstream ss;
    string str;
    str = "999:97 42:22 44:102300";
    ss << str;
    char ch;
    int temp, temp1;
    while (ss >> temp >> ch >> temp1) 
    {
        cout << temp << ":" << temp1 << endl;
    }
    cin.ignore();
}

Your code is not working because in the third iteration, the read was fine and didn't set the fail flag, it is set when the read is unsuccessful i.e. when it tries to in the 4th iteration.

As the read failed, the buffer still has the old values, which are printed(fail now returns true in 5th iteration as it failed in 4th)

Saksham
  • 9,037
  • 7
  • 45
  • 73
  • Well well, sorry but I still don't get it. iteration 1: checks for the fail bit, then temp and temp1 are set to 999 and 97. iteration 2: checks for fail bit, then sets variable to 42, 22. iteration 3: checks, assigns variables to 44, 102300. iteration 4: Since now the stringstream object has nothing to provide, hence the fail bit should be set, which should in turn break the loop? Then how can the fourth 'cout' get executed ? – Shivam Dixit Aug 17 '13 at 20:27
  • @ShivamDixit Fail bit is set when stream tries to fetch something but couldn't. Till 3rd iteration it could. In 4th it couldnt so `ss >> temp >> ch >> temp1` in 4th iteration sets the fail flag to true as it couldnt fetch. but by then you have passed the `fail()` statement so it is checked in the next iteration(5th). NOTE: Fail bit is set only after a failure. `fail()` just checks the flag is set or not. – Saksham Aug 18 '13 at 03:16
1

Because it didn't fail, simple as that. The read was succesful but you made the mistake of checking for errors too late.

You must check for fail condition before you use the objects you read into, otherwise you risk dealing with invalid data. You could write the loop this way:

while (1) {
    ss >> temp >> ch >> temp1;
    if (ss.fail()) break;
    cout << temp << ":" << temp1 << endl;
}

But the idiomatic way to do it is in @Shaksham's answer.

jrok
  • 54,456
  • 9
  • 109
  • 141