Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Requiring valid input with cout/cin

Tags:

c++

I have a game where the user needs to enter x and y coordinates within a certain range, one at a time. Right now my input code is as follows:

do {
    printf("\n");
    cout << "X: ";
    cin >> x;
    cout << "Y: ";
    cin >> y;
} while (cin.fail());

I'm new to c++ but reading documentation lead me to believe this was an acceptable method for verifying user input. It works perfectly when the input is valid, however when the input is of a different type (for instance entering "a") it infinitely loops with "X: Y: ". What do I need to do differently to have it wait for user input as if the lines were being read for the first time?

like image 216
Chris Avatar asked Nov 23 '25 03:11

Chris


1 Answers

You should check every single input operation:

std::cout << "X: ";
if (!(std::cin >> x)) { /* error */ }
std::cout << "Y: ";
if (!(std::cin >> y)) { /* error */ }

It's up to you how you want to handle the error. You could return early, break from a loop, throw an exception... it all depends.

Note that you could loop until you get something parseable, but that's dangerous if the user closes the input stream. Better to read line by line and parse:

std::cout << "Please enter an integer X: ";
int x;
bool success = false;

for (std::string line; std::getline(std::cin, line); )
{
    std::istringstream iss(line);
    if (iss >> x >> std::ws && iss.get() == EOF)  // #1
    {
        success = true;
        break;
    }
    std::cout << "Sorry, please try again: ";
}

if (!success)
{
    std::cerr << "Unexpected end of input stream!\n";
    std::exit(1);
}

This way, if the user presses [Ctrl]-D in the middle of the session, the program shuts down immediately and doesn't try to read more values from the closed input stream.

The condition on the line marked #1 tests both for a successful parsing of an integer as well as for having reached the end of the line (gobbling intermediate whitespace).

like image 131
Kerrek SB Avatar answered Nov 24 '25 19:11

Kerrek SB



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!