简体   繁体   中英

How to validate the user input in this case?

So for this program the user has to input a number from 1 to 4. Currently the program alerts the user if he mistakenly inputs a different number, but the issue is with characters. If the user inputs any type of character other than a number the loop becomes an infinite loop.

I would like to know if this is possible to accomplish in an intro level of C++ (much like the current code)

Here is the code

#include <iostream>
#include <iomanip>
#include <cstdlib>
#include <ctime>
using namespace std;

int main()
{
    int firstNum,
        secondNum,
        subFirstNum,
        subSecNum,
        operNum,
        num;               // User's input answer for operations
    bool temBool = true;   // Temporary boolean used in the while loop
    unsigned seed;         // Random generator seed

    // Use the time function to get a "seed" value for srand
    seed = time(0);
    srand(seed);

    //Start of the loop
    while (temBool) 
    {

    //Random generated operands
    firstNum = rand() % 40 + 10;
    secondNum = rand() % 40 + 10;

    // Set of randoms numbers for substraction where the denominator is always
    // lower than the numerator. 
    subFirstNum = rand() % 30 + 20;
    subSecNum = rand() % 10 + 10;

    // Menu of Math Tutor
    cout << "Math Tutor - Main Menu";
    cout << endl << endl;
    cout << "1. Adittion\n";
    cout << "2. Subtraction\n";
    cout << "3. Multiplication\n";
    cout << "4. Exit Program\n";
    cout << endl << endl;
    cout << "Choose your operation to practice (1-4) ";
    cin >> operNum; 
    cout << endl << endl;

    // Switch for the menu's options
    switch (operNum)
    {
            srand(seed);

    case 1:
        cout << "Working with addition\n";
        cout << setw(3) << firstNum << "\n"
             << "+" << secondNum << "\n"
             << "---\n";
        cout << "Your answer: ";
        cin  >> num;
            if(num == firstNum + secondNum)
            {
                cout << "Correct answer: " 
                     << firstNum + secondNum << " Congratulations!\n";
            }
            else
            {
                cout << "Correct answer: " 
                     << firstNum + secondNum << " Sorry!\n";
            }
        cout << endl << endl;
            break;
    case 2:
        cout << "Working with subtraction\n";
        cout << setw(3) << subFirstNum << "\n"
             << "-" << subSecNum << "\n"
             << "---\n";
        cout << "Your answer: ";
        cin  >> num;
            if(num == subFirstNum - subSecNum)
            {
                cout << "Correct answer: " 
                     << subFirstNum - subSecNum << " Congratulations!\n";
            }
            else
            {
                cout << "Correct answer: " 
                     << subFirstNum + subSecNum << " Sorry!\n";
            }
        cout << endl << endl;
            break;
    case 3:
        cout << "Working with multiplication\n";
        cout << setw(3) << firstNum << "\n"
             << "*" << secondNum << "\n"
             << "---\n";
        cout << "Your answer: ";
        cin  >> num;
            if(num == firstNum * secondNum)
            {
                cout << "Correct answer: " 
                     << firstNum * secondNum << " Congratulations!\n";
            }
            else
            {
                cout << "Correct answer: " 
                     << firstNum * secondNum << " Sorry!\n";
            }
        cout << endl << endl;
            break;
    case 4:
        cout << "Thank you for using Math Tutor.\n\n";
        temBool =  false;
            break;
    default:  
              cout << "Incorrect menu seletion. Please choose between 1 and 4.\n\n";
          break;
    return 0;
    }
    }
}

Once a stream state heads south due to invalid extraction, format error, etc, there's very little you can do with it besides detect it, determine if clearing the failure state is applicable, do so if it is, and move on. There are times when it is not applicable (such as arriving at EOF; not much good there).

Something like this:

#include <iostream>
#include <iomanip>
#include <cstdlib>
#include <ctime>
using namespace std;

int main()
{
    int firstNum,
    secondNum,
    subFirstNum,
    subSecNum,
    operNum,
    num;               // User's input answer for operations
    bool temBool = true;   // Temporary boolean used in the while loop

    // Use the time function to get a "seed" value for srand
    std::srand(static_cast<unsigned>(std::time(nullptr)));

    //Start of the loop
    while (temBool)
    {
        //Random generated operands
        firstNum = rand() % 40 + 10;
        secondNum = rand() % 40 + 10;

        // Set of randoms numbers for substraction where the denominator is always
        // lower than the numerator.
        subFirstNum = rand() % 30 + 20;
        subSecNum = rand() % 10 + 10;

        // Menu of Math Tutor
        cout << "Math Tutor - Main Menu";
        cout << endl << endl;
        cout << "1. Adittion\n";
        cout << "2. Subtraction\n";
        cout << "3. Multiplication\n";
        cout << "4. Exit Program\n";
        cout << endl << endl;
        cout << "Choose your operation to practice (1-4) ";

        // test for successful extraction
        if (!(std::cin >> operNum))
        {
            // yes there are times when you actually use .eof()
            if (std::cin.eof())
                break;

            // flush out the stream through the pending newline
            std::cin.clear();
            std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
            continue;
        }

        cout << endl << endl;

        // Switch for the menu's options
        switch (operNum)
        {
            case 1:
                cout << "Working with addition\n";
                cout << setw(3) << firstNum << "\n"
                << "+" << secondNum << "\n"
                << "---\n";
                cout << "Your answer: ";
                cin  >> num;
                if(num == firstNum + secondNum)
                {
                    cout << "Correct answer: "
                    << firstNum + secondNum << " Congratulations!\n";
                }
                else
                {
                    cout << "Correct answer: "
                    << firstNum + secondNum << " Sorry!\n";
                }
                cout << endl << endl;
                break;
            case 2:
                cout << "Working with subtraction\n";
                cout << setw(3) << subFirstNum << "\n"
                << "-" << subSecNum << "\n"
                << "---\n";
                cout << "Your answer: ";
                cin  >> num;
                if(num == subFirstNum - subSecNum)
                {
                    cout << "Correct answer: "
                    << subFirstNum - subSecNum << " Congratulations!\n";
                }
                else
                {
                    cout << "Correct answer: "
                    << subFirstNum + subSecNum << " Sorry!\n";
                }
                cout << endl << endl;
                break;
            case 3:
                cout << "Working with multiplication\n";
                cout << setw(3) << firstNum << "\n"
                << "*" << secondNum << "\n"
                << "---\n";
                cout << "Your answer: ";
                cin  >> num;
                if(num == firstNum * secondNum)
                {
                    cout << "Correct answer: "
                    << firstNum * secondNum << " Congratulations!\n";
                }
                else
                {
                    cout << "Correct answer: "
                    << firstNum * secondNum << " Sorry!\n";
                }
                cout << endl << endl;
                break;
            case 4:
                cout << "Thank you for using Math Tutor.\n\n";
                temBool =  false;
                break;
            default:  
                cout << "Incorrect menu seletion. Please choose between 1 and 4.\n\n";
                break;
                return 0;
        }
    }
}

Surround the switch with an if statement

if (operNum==1||operNum==2||operNum==3||operNum==4){
  ...
}

My organization has the following code for this sole purpose.

#include <cctype>
#include <cstdlib>
#include <string>

/**
 * @brief function returns the integer value of the string entered, negative
       numbers in the input string are not allowed. First non-digit character
       (including minus sign (-)) terminates parsing of the input string
 * @exception throws no exception, return value for every input
 * @param[in] input string containing the response of the user
 * @return <int> errorValue = -1, non-negative value is the response of the user
 */
int menuResponse(std::string input)
{
    int response = 0;
    int length = 0;
    response = atoi(input.c_str());   // <--- magic happens here
    // check for an error in the 1st character itself, only source of false 0 
    // as a response value
    if (isdigit(input[0]))
    {
        return response;
    }
    else
    {
        return -1;
    }
}

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