Home > Enterprise >  how to make cin only take integer inputs
how to make cin only take integer inputs

Time:05-20

i new to programming and we are required to create a program that dont exit when the user inputs the wrong input, but i only learned the basics so far.. i already solved when the number is above and below 100 but when the user accidentally inserted a non integer it will go into a error loop. btw this is an average calculator.

#include <iostream>

using namespace std;

int main()
{
    int num[100];
    int n;
    double sum, average;

    cout << "how many numbers will you input?: ";
    cin >> n;

    while ( n > 100 || n <= 0 )
    {
        cout << "Error! number should in range of (1 to 100) only." << endl;
        cout << "Enter the number again: ";
        cin >> n;
    }

    for ( int i = 0; i < n;   i )
    {
        cout << i   1 << ". Enter number: ";
        cin >> num[i];
        sum  = num[i];
    }

    average = sum / n;
    cout << "Average = " << average;
}

CodePudding user response:

If std::istream::operator >> fails, it will set failbit. Therefore, you should check failbit (for example by calling std::cin.fail()) to see whether the conversion was successful, before using the result of the conversion.

If the conversion fails due to bad input, then the next call to std::istream::operator >> will automatically fail due to failbit being set. Therefore, if you want to attempt input again, you will first have to clear failbit, by using the function std::cin.clear().

Also, you will have to discard the bad input that caused the conversion to fail, because otherwise, the next time you call std::istream::operator >>, the conversion will fail again for the same reason. In order to clear the bad input, you can use std::cin.ignore(), like this:

std::cin.ignore( std::numeric_limits<std::streamsize>::max(), '\n' );

However, I don't recommend that you use std::istream::operator >>, because its behavior not always intuitive. For example, it

  1. does not always read a whole line of input and
  2. accepts 6abc as valid input for the number 6.

In my experience, if you want proper input validation of integer input, it is usually better to write your own function that reads a whole line of input using std::getline and converts it with std::stoi. If the input is invalid, then the function should automatically reprompt the user.

In my example below, I am calling this function get_int_from_user.

If you want to additionally ensure that the input is in a certain range, then you can call the function get_int_from_user in an infinite loop, and break out of that loop once you determine that the input is valid.

#include <iostream>
#include <string>
#include <sstream>

int get_int_from_user( const std::string& prompt );

int main()
{
    int nums[100];
    int n;
    double sum;

    //repeat loop forever, until input is good
    for (;;) //equivalent to while(true)
    {
        n = get_int_from_user( "How many numbers will you input? " );

        if ( 1 <= n && n <= 100 )
            //input is good
            break;

        std::cout << "Error! Number should in range of (1 to 100) only.\n";
    }

    //read one number per loop iteration
    for( int i = 0; i < n; i   )
    {
        std::ostringstream prompt;

        prompt << "Enter number #" << i   1 << ": ";

        nums[i] = get_int_from_user( prompt.str() );

        sum  = nums[i];
    }

    std::cout << "Average: " << sum / n << '\n';
}

int get_int_from_user( const std::string& prompt )
{
    std::string line;
    std::size_t pos;
    int i;

    //repeat forever, until an explicit return statement or an
    //exception is thrown
    for (;;) //equivalent to while(true)
    {
        //prompt user for input
        std::cout << prompt;

        //attempt to read one line of input from user
        if ( !std::getline( std::cin, line ) )
        {
            throw std::runtime_error( "unexpected input error!\n" );
        }

        //attempt to convert string to integer
        try
        {
            i = std::stoi( line, &pos );
        }
        catch ( std::invalid_argument& )
        {
            std::cout << "Unable to convert input to number, try again!\n";
            continue;
        }
        catch ( std::out_of_range& )
        {
            std::cout << "Out of range error, try again!\n";
            continue;
        }

        //The remainder of the line is only allowed to contain
        //whitespace characters. The presence of any other
        //characters should cause the entire input to get rejected.
        //That way, input such as "6sdfj23jlj" will get rejected,
        //but input with trailing whitespace will still be accepted
        //(just like input with leading whitespace is accepted by
        //the function std::stoi).
        for ( ; pos < line.length(); pos   )
        {
            if ( !std::isspace( static_cast<unsigned char>(line[pos]) ) )
            {
                std::cout << "Invalid character found, try again!\n";

                //we cannot use "continue" here, because that would
                //continue to the next iteration of the innermost
                //loop, but we want to continue to the next iteration
                //of the outer loop
                goto continue_outer_loop;
            }
        }

        //input is valid
        return i;

    continue_outer_loop:
        continue;
    }
}

This program has the following behavior:

How many numbers will you input? 200
Error! Number should in range of (1 to 100) only.
How many numbers will you input? -31
Error! Number should in range of (1 to 100) only.
How many numbers will you input? 4
Enter number #1: 1
Enter number #2: 2
Enter number #3: 6abc
Invalid character found, try again!
Enter number #3: five
Unable to convert input to number, try again!
Enter number #3: 3
Enter number #4: 4
Average: 2.5

CodePudding user response:

#include <iostream>
using namespace std;
int avg(int sum, int n)
{
    int average;
    average = sum/n;
    cout<<"Avg = "<<average;
}
int main()
{
int n;
int num[n];
int sum;
cout << "how many numbers will you input?: ";
cin >> n;
while(n>100||n<=0)
{
cout << "Error! number should in range of (1 to 100) only." << endl;
cout << "Enter the number again: ";
cin >> n;
}
for(int i = 0; i < n;   i)
{
cout << i   1 << "Enter number: ";
cin >> num[i];
if(!cin)
{
      cout << "Wrong Choice. " << endl;
      cin.clear();
      cin.ignore(256, '\n');//to ignore number not in range of integer
      /*we do this because in case of wrong input this will run for 1 of the i values of loop so in case of 5
       input if 1 is wrong it will take avg of 4 only b/c one was wrong so in order to take 5 input sum increment n*/
       n  ;
      continue;
}
else
{
sum  = num[i];
}
}
cout<<"Sum  = "<<sum<<endl;
avg(sum,n);
}
  • Related