问题
I am working on the game 'Hex' for a C++ class, and am having trouble understanding how to make sure cin is reading the correct type. I have done some research and I'm close, but here is my problem:
int i, j;
while(true){
cin >> i;
if(cin.fail() ){ //if type wasn't right
cin.clear(); //clear stream
cin.ignore(); //ignore left over data
cout << "First value is invalid input! Valid coordinates are in range 0 to " << size - 1 << endl;
continue;
}
cin >> j;
if(cin.fail() ){ //if type wasn't right
cin.clear(); //clear stream
cin.ignore(); //ignore left over data
cout << "Second value is invalid input! Valid coordinates are in range 0 to " << size - 1 << endl;
continue;
}
if(i < 0 or i >= size or j < 0 or j >= size){
//prompt that input is wrong
cout << "Invalid input! Valid coordinates are in range 0 to " << size - 1 << endl;
continue;
}
There are break statements there, it does get out okay. My problem is with runs such as this:
Player 1's turn
Enter the row and column coordinate with only a space inbetween
a b
First value is invalid input! Valid coordinates are in range 0 to 10
First value is invalid input! Valid coordinates are in range 0 to 10
u 8
First value is invalid input! Valid coordinates are in range 0 to 10
8 u
It doesn't detect that the second value was incorrect when they both were, and when only the second is incorrect, it doesn't detect it as an error. I have looked at http://www.cplusplus.com/reference/iostream/cin/?kw=cin and it doesn't even have the documentation for the fail, clear, and ignore functions, so I don't fully understand them. Thanks in advance!
回答1:
u 8
First value is invalid input! Valid coordinates are in range 0 to 10
8 u
As cin >> i;
fails because of u
, the loop is repeated, but only the first character following in the cin
stream, a space, is consumed by cin.ignore();
. As the loop starts again, cin >> i;
is executed using what's left in the stream, in this case 8
. This means that after the error message First value is invalid input! Valid coordinates are in range 0 to 10
, the program is actually waiting on cin >> j;
. When 8 u
is entered, it reads 8
first and assigns its value to j, meaning there is no failure. The loop ends, and u
is left in the stream.
To fix this, change cin.ignore();
by cin.ignore(numeric_limits<streamsize>::max(), '\n');
. Instead of ignoring only the next character, which is a space in this example, it'll ignore the rest of the line, effectively resetting the cin
stream. You'll need to include the <limits>
header.
来源:https://stackoverflow.com/questions/16726657/checking-for-valid-type-input-using-stdcin-c