简体   繁体   中英

C++ input validation while loop not terminating

I'm a student in an intro C++ computer science course, and this is the first time I've posted here. We've just learned about while loops, and though the assignment doesn't require it, I'm trying to do input validation on this assignment. The program is meant to read a list of numbers and figure out the positions in that list where the first and last 8 are. So if I have a list of four numbers (1, 8, 42, 8), then the first and last 8 positions are 2 and 4. The size of the set is determined by the user.

I was trying to make a while loop that tested to be sure that what the user entered was actually a digit, but when I try entering in something like "." or "a" the loop goes on infinitely and doesn't terminate. I can't find my error, and as far as I can tell I'm using exactly the same syntax as what's in my textbook. Can someone show me what's wrong with my while loop?

int numbers,            //How large the set will be
    num,                //What the user enters for each number
    first8position = 0, //The first position in the set that has an 8
    last8position = 0;  //The last position in the set that has an 8

//Prompt the user to get set size
cout << "How many numbers will be entered?  ";
cin >> numbers;

//Loop to get all the numbers of the set and figure out
//which position the first and last 8 are in
for (int position = 1; position <= numbers; position++)
{
    cout << "Enter num:  ";
    cin >> num;

    //If num isn't a digit, prompt the user to enter a digit
    while (!isdigit(num))
    {
        cout << "Please enter a decimal number:  ";
        cin >> num;
    }

    //If num is 8, and first8position still isn't filled,
    //set first8position to the current position.
    //Otherwise, set last8position to the current position.
    if (num == 8)
    {
        if (first8position == 0)
            first8position = position;
        else
            last8position = position;
    }


}

//If the set had an 8, print what its position was
if (first8position != 0)
    cout << "The first 8 was in position " << first8position << endl;

//If there was more than one 8, print the last 8 position.
//Otherwise, the first and last 8 position are the same.
if (last8position != 0)
    cout << "The last 8 was in position " << last8position << endl;
else
    cout << "The last 8 was in position " << first8position << endl;

//If there were no 8s, say so.
if (first8position == 0)
    cout << "Sorry, no eights were entered.";

return 0;

}

Two issues are leading to your infinite loop:

First, with cin >> num , you try to read in an integral value. If a user enters something like a or . , which cannot be the start of an integral value, nothing is read in and the a or . remain in the input buffer; Hence, every subsequent cin >> num will immediately fail (without giving the user the chance to enter something, since the a or . are still in the input buffer and will remain there). So in such a case you will have to consume these characters from cin , eg by using cin.ignore , and you will have to reset the failbit , which is set in this case, too.

Second, note that isdigit(int c) checks if the ASCII -value c is a digit, ie if c >= 48 && c <= 57 . So your check isdigit(num) will fail until a user enters a number between 48 and 57 .

See the following code demonstrating how to deal with input failures. Hope it helps.

int main() {

    int num;
    cin >> num;
    while (!cin.eof() && cin.fail()) {  // failure when extracting an integral value?
        cout << "not an integral value." << endl;

        // clear failbit
        cin.clear();

        // remove characters that are still in the input buffer (until next end of line)
        cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');

        // next try to read in an integer
        cin >> num;
    }
    if (!cin.eof()) {
        cout << "juu:" << num << endl;
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM