How to convert string to int, and check for errors...

I am used to programming, as a hobbyist, in C#. I've been trying to get accustomed to C++, but, I have been having issues accomplishing a simple task.

I want to accept input from the user as a string and convert it to an integer or double while simultaneously checking for bad input. (i.e: "54" is acceptable input, but "5&*4" is not.)

In C#, I've accomplished this using Convert.ToInt32as shown in the following function (yes, this function only checks if it can/cannot be converted - it doesn't actually return a converted value):
1
2
3
4
5
6
7
8
9
public static bool IsInteger (string InputToCheck)
		{
			try {
				Convert.ToInt32 (InputToCheck);
			} catch {
				return false;
			}
			return true;
		}


Although the above may not be the most elegant solution, it does work. I have been trying to duplicate the functionality in C++, but, every solution I've been able to come up with will still allow bad input to get through. For example, using things like atoi will still let "5#$" through and just truncate the value to "5"

Any suggestions? This seems like it should be a simple task -- but, I can't seem to figure it out.

Thanks!
Use the family of functions

int stoi(const string& str, size_t *idx = 0, int base = 10);
long stol(const string& str, size_t *idx = 0, int base = 10);
unsigned long stoul(const string& str, size_t *idx = 0, int base = 10);
long long stoll(const string& str, size_t *idx = 0, int base = 10);
unsigned long long stoull(const string& str, size_t *idx = 0, int base = 10);

They are standard function and generate exceptions if conversions are impossible.
Something like the following, perhaps?

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
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
#include <sstream>
#include <iostream>
#include <string>
#include <cctype>


// This function will return false if there is
// any leading or trailing whitespace in the string.
bool IsInteger( const std::string& s )
{
    if ( s.size() == 0 )
        return false ;

    if ( !(std::isdigit(s[0]) || s[0] == '-') )
        return false ;

    for ( unsigned i=1 ;  i<s.size();  ++i )
        if ( !std::isdigit(s[i]) )
            return false ;

    return true ;
}

int ToInteger( const std::string& s )
{
    std::istringstream in(s) ;

    int returnValue ;
    in >> returnValue ;

    return returnValue ;
}

int main()
{
    std::string strings[] =
    {
        "5",
        "5.",
        "5r2",
        "nmo",
        "32 02",
        "3245S"
    };

    for ( unsigned i=0; i< sizeof(strings)/sizeof(strings[0]); ++i )
    {
        std::cout << strings[i] << ' ' ;

        if ( IsInteger(strings[i]) )
            std::cout << "coverts to " << ToInteger(strings[i]) << '\n' ;
        else
            std::cout << "is not an integer\n" ;
    }
}
Last edited on
@cire

You forgot the plus sign.:)

1
2
    if ( !(std::isdigit(s[0]) || s[0] == '-' || s[0] == '+') )
        return false ;


And what about floating point numbers?:)
You are correct, '+' being a valid symbol at the beginning of a number didn't occur to me, although it obviously should be. As for floating point numbers, they aren't integers. That's why I included element 1 in strings. The OP can decide whether the behavior is correct for his purposes.
Topic archived. No new replies allowed.