Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to make cin take only numbers

Tags:

c++

Here is the code

double enter_number()
{
  double number;
  while(1)
  {

        cin>>number;
        if(cin.fail())
        {
            cin.clear();
            cin.ignore(numeric_limits<streamsize>::max(), '\n');
            cout << "Invalid input " << endl;
        }
        else
        break;
        cout<<"Try again"<<endl;
  }
  return number;
}

My problem is that when I enter something like 1x, then 1 is taken as input without noticing the character that is left out for another run. Is there any way how to make it work with any real number e.g. 1.8?

like image 895
user1426900 Avatar asked May 31 '12 07:05

user1426900


1 Answers

When cin encounters an input it can't properly read in to the variable specified (such as inputing a character into an integer variable), it goes into an error state and leaves the input in it's buffer.

You have to do several things to properly handle this scenario.

  1. You have to test for this error state.
  2. You have to clear the error state.
  3. You have to either alternatively handle the input data that generated the error state, or flush it out and reprompt the user.

The following code provides one of numerous methods of doing these three things.

#include<iostream>
#include<limits>
using namespace std;
int main()
{

    cout << "Enter an int: ";
    int x = 0;
    while(!(cin >> x)){
        cin.clear();
        cin.ignore(numeric_limits<streamsize>::max(), '\n');
        cout << "Invalid input.  Try again: ";
    }
    cout << "You enterd: " << x << endl;        
}

You could just pass in some large value to cin.ignore like 1000 and it's likely to behave exactly the same for all practical purposes.

You can also test cin after the input attempt and handle it that way, something like if(!cin){//clean up the error} .

Check out the istream reference for other member functions to handle stream state: http://cplusplus.com/reference/iostream/istream/

like image 57
Shiven Avatar answered Nov 15 '22 20:11

Shiven