Mr Thysbe
Mr Thysbe

Reputation: 1

Why does this code get stuck in an infinite loop if I input a letter?

int readUntilValidBaseRead( int &base )
{
base = 0;
while ( base > 9 || base < 2)
{
    cout << "Enter Base: " << endl;
    cin >> base;
    if (base > 1 && base < 10)
    {
        return base;
    }
    else 
    {
        cout << "a valid base number is in the range of 2 to 9 inclusively" << endl;
        base = 0;
    }
}

}

For an assignment I'm doing, I need to use a function to get a base, and this is what I wrote. If any number is input, the code works fine. If I input f, then the code gets stuck repeating

a valid base number is in the range of 2 to 9 inclusively 
   Enter Base:

Upvotes: 0

Views: 106

Answers (3)

Some programmer dude
Some programmer dude

Reputation: 409356

It's because if you don't enter input that can be parsed as an integer, then the input will not be extracted and will stay in the input buffer so the next iteration of the loop you will read the exact same input as previous iteration and have the same problem all over again.

This is the reason I recommend you use std::getline to read the whole line into a string, and then use std::istringstream to try and extract/parse the data.

You also need to remember that most input (and output for that matter) operations return a reference to the stream, and that it can be used as a boolean expression, so you can use something like

std::istringstream is(someString);
if (is >> base)
{
    // Successfully read and parsed an integer
}
else
{
    // Some error occurred
}

Upvotes: 0

Xirema
Xirema

Reputation: 20396

Inputting a letter causes the cin object to get stuck in an error state, failing to read to base regardless of what you feed it afterwards.

You have two options for solving this.

You could either check & clear the error after it occurs, like so:

if(!std::cin) {
    std::cin.clear();
    std::cin.ignore(std::numeric_limits<std::streamsize>::max(),'\n');
}

Or you could read entire lines at once, and parse the lines for numbers:

std::string line;
std::getline(std::cin, line);
int value = std::stoi(line);

Upvotes: 0

Thomas Matthews
Thomas Matthews

Reputation: 57728

You need to check the result or status of this statement:

cin >> base;

It will fail if the input is not a number. The value of base when the input fails is undefined.

Try this:

if (cin >> base)
{
  // User input a valid number
}

Upvotes: 1

Related Questions