is this a bug of g++?

Hello,
Im using the g++(g++ Ubuntu/Linaro 4.4.4-14ubuntu5 4.4.5) and im trying to compile a small snippet code and got into an endless loop.I recompiled that in VS2010 under Windows 7 and the answer is as expected.so i wonder is this a bug of g++?here is my code.

#include<iostream>

using namespace std;

int main()
{
	int val;

	while(cin>>val,!(cin.eof())){
		if(cin.fail()){
			cerr<<"bad data,try again"<<endl;;
			cin.clear();
			continue;
		}else if(cin.good()){
			cerr<<"you entered :"<<val<<endl;
			break;
		}
}
}

---------- Post updated at 04:24 AM ---------- Previous update was at 04:07 AM ----------

Actually,the code::blocks with Mingw runs the code below OK while my g++ gets a endless loop.

#include <iostream>
using namespace std;

int main()
{
	int val;

	while(cin>>val,!cin.eof()){
		if(cin.fail()){
			cerr<<"failed,try again"<<endl;
			cin.clear();
			cin.sync();      //ADD THIS
		}else if(cin.good()){
			cout<<"you entered: "<<val<<endl;
			break;
		}
	}
}

My understanding is you need to flush the "bad" data.
cin.clear() doesn't clear the buffer, it clears error conditions.

#include<iostream>

using namespace std;

int main()
{
    int val;
    string bad;

    while(cin>>val,!(cin.eof()))
    {
        if(cin.fail())
        {
            cerr<<"bad data,try again"<<endl;;
            cin.clear();
            cin>>bad;
            continue;
        }
        else if(cin.good())
        {
            cerr<<"you entered :"<<val<<endl;
            break;
        }
    }
}

yes,i think your solution is same as adding cin.sync().

It isn't the same, at least with my tests here. cin.sync() doesn't flush the buffer so I experience the same issue with it. Reading cin in a string breaks the endless loop.

1 Like

yeah,sometimes it won't work by adding sync(),such as with my platform and my compiler version,as i said above,mingw works fine.Your solution is a good way to handle this problem.But i'm wondering is there a portable way to eliminate such a problem.Because we may do something like:
cin>>a_int>>a_string>>a_double;
what if the error occurs when we get the first value(enter a string when needs a integer)?we have to use getline() to flush the invalid data.

It sounds like the same or similar problem as scanf() in C: It throws up on bad data but doesn't actually discard the bad data.

In C the usual approach is to read strings line-by-line with fgets or getline (fgets preferred because there's some very broken getline implementations out there), then feed the line into sscanf. Whether sscanf succeeds or not, the data is out of the input stream and out of your way.

C++ doesn't have special string-only functions, it uses stringstream to make a string act like ss>>var>>var; instead. Whether reading your vars from the string succeeds or not, the data is out of cin and can't come back to haunt you.

Here's an example.