0
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:
Mr Thysbe
  • 1
  • 1
  • 1
    you need to check `cin.good()` after reading `base`. "f" is not a number and continually fails to read it. – kmdreko Apr 01 '16 at 20:16
  • It's helpful if you explain why you think it shouldn't get stuck in an infinite loop. Where do you think it would exit the loop? – David Schwartz Apr 01 '16 at 20:20
  • The answers here: https://youtu.be/TANC4VI8vF4?t=49. It is a bit loud. – Captain Giraffe Apr 01 '16 at 20:21
  • Possible duplicate of [How to handle wrong data type input](http://stackoverflow.com/questions/10349857/how-to-handle-wrong-data-type-input) – Barmar Apr 01 '16 at 20:53

3 Answers3

1

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
}
Thomas Matthews
  • 56,849
  • 17
  • 98
  • 154
0

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
}
Some programmer dude
  • 400,186
  • 35
  • 402
  • 621
0

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);
Xirema
  • 19,889
  • 4
  • 32
  • 68