Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to Limit Input to Numbers Only

I recently created a program that will create a math problem based on the user input. By entering either 1-4 the program can generate a problem or the user can quit by entering 5. The only problem I am having is that when I enter a character the program goes into an infinite loop. What function could I use to check if the input is not a number so I can display an error message?


//CIS180 Assignment #4
#include <iostream>
#include <iomanip>
#include <cstdlib>
#include <ctime>
using namespace std;

int main()
{
    //Declare variables.
    int num1, num2, menuNum;
    int addInput, subInput, multInput, divInput;
    int addAnswer, subAnswer, multAnswer, divAnswer;
    int addSolution, subSolution, multSolution, divSolution;
    srand(time(0));
    //Display menu.
    cout << "Menu" << endl;
    cout << "1. Addition problem" << endl;
    cout << "2. Subtraction problem" << endl;
    cout << "3. Multiplication problem" << endl;
    cout << "4. Division problem" << endl;
    cout << "5. Quit this program" << endl << endl;
    cout << "Enter your choice (1-5): " << endl;
    cin >> menuNum;
    //Loop that will provide math problems when user inputs number.
    while(menuNum != 5)
    {
        //Check if the input is valid.
        while((menuNum < 1) || (menuNum >5))
        {
            cout << "The valid choices are 1, 2, 3 , 4, and 5. Please choose: " << endl;
            cin >> menuNum;
        }
        //Generate two random numbers for addition and display output.
        if(menuNum == 1)
        {
            num1 = rand()%500 + 1;
            num2 = rand()%500 + 1;
            addSolution = num1 + num2;
            cout << setw(5) << right << num1 << endl;
            cout << setw(2) << left << "+" << setw(3) << right << num2 << endl;
            cout << setw(5) << fixed << "-----" << endl;
            cin >> addAnswer;
            //Check if the addition answer input is correct.
            if(addAnswer != addSolution)
                cout << "Sorry, the correct answer is " << addSolution << "." << endl;
            else if(addAnswer == addSolution)
                cout << "Congratulations! That's right." << endl << endl;
        }
        .
            .
            .
like image 383
big_beef Avatar asked Dec 15 '22 06:12

big_beef


1 Answers

First off, you should detect whether your input attempt was successful: always check after reading that the read attempt was successful. Next, when you identify that you couldn't read a value you'll need to reset the stream to a good state using clear() and you'll need to get rid of any bad characters, e.g., using ignore(). Given that the characters were typically entered, i.e., the user had to hit return before the characters were used it is generally reaonable to get of the entire line. For example:

for (choice = -1; !(1 <= choice && choice <= 5); ) {
    if (!(std::cin >> choice)) {
         std::cout << "invalid character was added (ignoring the line)\n";
         std::cin.clear();
         std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
    }
}

The use of std::numeric_limits<std::streamsize>::max() is the way to obtain the magic number which makes ignore() as many characters as necessary until a character with the value of its second argument is found.

like image 57
Dietmar Kühl Avatar answered Dec 24 '22 13:12

Dietmar Kühl