简体   繁体   中英

How come if I enter a letter input my program gets stuck in its while loop?

Sorry if I fail to be clear enough or make any mistakes, this is my first time posting.

My code runs without errors when complied but the first while loop (in int main ) gets stuck looping whenever a user types a letter (like "a" ) for cin >> select; instead of the required 1 , 2 , or 3 .

However, when I input "4" or any other random string of numbers, it runs fine and goes to my error message like it should.

Why is this and what can I do to make it run normally? (run the error message in response to letters entered as if they were numbers).

My code:

#include <iostream>
#include <string>
using namespace std;

void calculator();
void unavailableitem();

int main()
{
    string select;
    while (true)
    {
        cout << "\t[Main Menu]\n";
        cout << " 1. Calculator\n";
        cout << " 2. [unavailable]\n";
        cout << " 3. [unavailable]\n";
        cout << "\n Enter the number of your selection: ";
        cin >> select;

        if (select == "1")
        {
            cout << endl;
            calculator();
            break;
        }
        else if (select == "2")
        {
            unavailableitem();
            break;
        }
        else if (select == "3")
        {
            unavailableitem();
            break;
        }
        else
            cout << "\nInvalid response.\n";
    }
}

void unavailableitem()
{
    string react;
    cout << "\n \t [ITEM UNAVAILABLE]\n";
    while (true)
    {
        cout << "\nEnter 'menu' to return to main menu: ";
        cin >> react;

        if (react == "menu")
        {
            cout << endl;
            main();
            break;
        }
        else
            cout << "\nInvalid response.\n";
    }
}

void calculator()
{
    int choice;
    double num1;
    double num2;
    double answer;
    string choicesymbol;

    cout << "List of operations:\n";
    cout << " 1. Addition\n";
    cout << " 2. Subtraction\n";
    cout << " 3. Multiplication\n";
    cout << " 4. Division\n";
    cout << "Enter the number on the left to pick an operation: ";
    cin >> choice;
    cout << "\nEnter number 1: ";
    cin >> num1;
    cout << "\nEnter number 2: ";
    cin >> num2;

    if (choice == 1)
    {
        answer = num1 + num2;
        choicesymbol = " + ";
    }

    if (choice == 2)
    {
        answer = num1 - num2;
        choicesymbol = " - ";
    }

    if (choice == 3)
    {
        answer = num1 * num2;
        choicesymbol = " * ";
    }

    if (choice == 4)
    {
        answer = num1 / num2;
        choicesymbol = " / ";
    }

    cout << endl;
    cout << num1 << choicesymbol << num2 << " = " << answer;
}

New code:

#include <iostream>
#include <string>
using namespace std;

void calculator();
void unavailableitem();


int main()
{
    int select;
    while (true)
    {
        cout << "\t[Main Menu]\n";
        cout << " 1. Calculator\n";
        cout << " 2. [unavailable]\n";
        cout << " 3. [unavailable]\n";
        cout << "\n Enter the number of your selection: ";
        cin >> select;

        if(!(cin >> select))
        {
        cout << "Input must be an integer.\n";
        cin.clear();
        continue;
        }
        else if (select == 1)
        {
            cout << endl;
            calculator();
            break;
        }
        else if (select == 2)
        {
            unavailableitem();
            break;
        }
        else if (select == 3)
        {
            unavailableitem();
            break;
        }
    }
}



void unavailableitem()
{
    string react;
    cout << "\n \t [ITEM UNAVAILABLE]\n";
    while (true)
    {
        cout << "\nEnter 'menu' to return to main menu: ";
        cin >> react;

        if (react == "menu")
        {
            cout << endl;
            return;
            break;
        }
        else
            cout << "\nInvalid response.\n";
    }
}

void calculator()
{
    int choice;
    double num1;
    double num2;
    double answer;
    string choicesymbol;

    cout << "List of operations:\n";
    cout << " 1. Addition\n";
    cout << " 2. Subtraction\n";
    cout << " 3. Multiplication\n";
    cout << " 4. Division\n";
    cout << "Enter the number on the left to pick an operation: ";
    cin >> choice;
    cout << "\nEnter number 1: ";
    cin >> num1;
    cout << "\nEnter number 2: ";
    cin >> num2;

    if (choice == 1)
    {
        answer = num1 + num2;
        choicesymbol = " + ";
    }

    if (choice == 2)
    {
        answer = num1 - num2;
        choicesymbol = " - ";
    }

    if (choice == 3)
    {
        answer = num1 * num2;
        choicesymbol = " * ";
    }

    if (choice == 4)
    {
        answer = num1 / num2;
        choicesymbol = " / ";
    }

    cout << endl;
    cout << num1 << choicesymbol << num2 << " = " << answer;
}

Ad Ed Heal mentioned, the issue here is cin 's failbit. When you do cin >> choice , and the user types "a", then the conversion to int fails. This sets cin 's failbit, making all future reads from it fail until the failbit is cleared. So the next time you reach cin >> choice , the user won't even get to type anything.

You can use cin.clear() to restore to working order.

To do this a bit more robustly, you could do something like

while(true)
{
    cout >> "Enter choice [1-4]: ";
    if(!(cin >> choice))
    {
        cout << "Input must be an integer.\n";
        cin.clear();
        continue;
    }
    do_stuff_with_choice();
 }    

I am a newbie to programming in general, but playing with your code and looking up stuff made me find some sort of solution. The cin.clear only clears the error log of the input, and I believe that it still retains the value of the letter.

What you should add right after is a cin.ignore(#,'\\n') (# being a very, very large number) to have it avoid the line and skip right through it.

Found the solution in another question that explains the use of both cin commands.

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