Validating user input for numeric values

Hi, I'm new to C++ and ran into a problem trying to validate user input for a double value. This is what I've tried to do so far (after putting together what I've found through google):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
#include <iostream>
#include <string>

using namespace std;

int main() 
{
        double number=0;
        string buffer;
        string name;

        cout<<"Enter number: ";
	cin>>number;
	cin.ignore();

	while(cin.fail())
	{
		cin.clear();
		getline(cin, buffer);
		cout<<"Invalid input - please enter a number: ";
		cin>>rate;
		cin.ignore();
		buffer=" ";
	}

       cout<<"Enter name: ";
       getline(cin, name);
       cout<<endl;

       cout<<number<<endl;
       cout<<name<<endl;

       return 0;
}


The code works correctly when string starting with char (eg. abc or xyz123) is entered, but not when a string starting with numbers (eg. 123xyz). I suppose it's because cin reads 123 into number and stops when a char is encountered. Is there a way to recognise that strings like 123xyz is an invalid input and to disregard the whole input?

Any help is greatly appreciated. Thanks!
You could use std::getline into a temporary string. Check each character against is_digit() and then return if there was a failure.
Last edited on
I can't seem to find much info on is_numeric(), is it a standard C++ function?
Sorry. I meant to call it isdigit(). Its from cctype library, and is sometimes automatically included when compiling CPP, so you don't need to #include the cctype library. If you get an error it doesn't exist, include cctype.
Last edited on
Here is some sample code I wrote on the matter:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
#include <iostream> // Required headers
#include <string>
#include <sstream>

bool isValidInt(const std::string& str)
{
    std::string::const_iterator it;
    for (it = str.begin(); it != str.end(); ++it)
        if(!isdigit(*it))
            return false;
    
    return true;
}

int toInt (const std::string &str)
{
    int x;
    std::istringstream ss(str);
    ss >> x;
    return x;
}

int getInteger ()
{
    std::string tmp;
    
    
    while (tmp.empty() || !isValidInt(tmp))
        std::getline(std::cin, tmp);
        
    return toInt(tmp);
}

int main ()
{
    int one = getInteger();
    std::cout << one << std::endl;
}
Hey, thanks a lot for your help! Just one more thing: I need to store a double value from the user input, not a int, so I modified your code to convert into double. I'm not familiar with istringstream though, so could u help me take a look to see if I modified it correctly? Seems to work though :D

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
using namespace std;

bool isValid(const string& str)
{
    string::const_iterator it;
    for (it = str.begin(); it != str.end(); ++it)
        if(!isdigit(*it) && *it != '.')
            return false;
    
    return true;
}

double toDouble (const string &str)
{
    double x;
    istringstream ss(str);
    ss >> x;
    return x;
}

Topic archived. No new replies allowed.