Hi everyone,
How do I make sure that user input is of integer data type. not char nor alphanumeric..? when the user inputs character string or alphanumerics it should output "Please enter an integer" Is there sopme wayh to do this?
Thanks.

Recommended Answers

All 21 Replies

If they have input only integer data then all there should be is a string of digits.

  1. So get you get a line of input

  2. Extract an integer from it
  3. Verify the rest of the line is blank

If either step 2 fails or the rest of the line is not blank at step 3 then you have an input error.

You can use getline for step 1 and then a stringstream for steps 2 and 3.

There sure is!

Lookup the function atoi()

atoi() is unlikely to help because it has no error output, you could use strtol() however neither of those are C++ they are part of the C standard library and C++ provides the same functionality through the use of stringstreams.

First of all thank you Banfa & Ketsuekiame for your replies. I've checked the net for the said atoi() & strtol () functions, obviously they are above my current programming capabilties. I think the 3 steps banfa proposed is reasonable for me. But again, I don't know how exactly to implement them. By extracting, do you mean using cin.ignore(x,'\n') function? Thank you.

atoi() returns 0 on error. strtol() is the same function but converts it to long int.

If the text length is greater than 1 and the output is 0, that would indicate an error. Unless someone really wanted to put 000 in there or something.

Using stringstream to cast to int will also fail with output of 0 if the characters are not digits. Admittedly, stringstream is the more C++ way to do it.

No I mean more like

string line;
int value;
istringstream iss;

getline(cin, line); // Get a ine of input from user
iss.str(line);      // Put it into a stringstream for processing
iss >> value;       // Get an integer value

// At this point you can check the status bits of iss for failure 
// to convert the integer and you can get what is left in the 
// stringstream and see if it contains any additional characters

atoi() returns 0 on error. strtol() is the same function but converts it to long int.

If the text length is greater than 1 and the output is 0, that would indicate an error. Unless someone really wanted to put 000 in there or something.

Using stringstream to cast to int will also fail with output of 0 if the characters are not digits. Admittedly, stringstream is the more C++ way to do it.

You have answered your own question atoi does not return 0 on error 0 is returned for a number of reasons so a 0 return does not equate to a definite error.

strtol is not the same function because it returns a pointer to where the conversion finished so you can easily tell if the conversion finished because it reached the end of the string, white space or an invalid character. Also strtol will handle bases other than 10 which atoi wont but that isn't really relevant here.

Using stringstream with fail with the failbit set if the input characters are not digits. You can not use the output value of convert to integer as a test for success because there are no invalid output values.

Edit: Moved to PM as off-topic

Well thank you both for taking your time. It's sure that I have to read a lot more to be able to understand your comments. First I have to learn what istringstream is, working logic of getline(cin, line) etc. If you know some good online resources which might help me with learning c++, that would be appreciated if you share them. Thank you again.

Honestly, Google is your best bet.

Then if you're still stuck and you're using Visual C++ (Visual Studio et al.) then use the MSDN and look up functions specifically.

CPP Reference may be another good place to start

Thank you all..Browsing the sites now.

however neither of those are C++ they are part of the C standard library and C++ provides the same functionality through the use of stringstreams.

Just chiming in with a minor correction. atoi and strtol are most certainly C++. You shouldn't buy into the "pure C++" BS that encourages one to eschew all things inherited from C that have a C++ counterpart.

In this particular case, I've often found stringstreams to have a statistically significant overhead when compared to strtol (atoi is evil, of course, and should be ignored as a viable solution). Just because the functionality is the same doesn't mean the two options are equivalent. In performance critical code I've used strtol because it was just plain faster.

A fair point and I probably should have pointed out that the C standard library is available in C++.

What I was trying to combat was the tendency of people who have learnt C first to just use the C method they know rather than looking for the C++ way even if they then discard that method as inefficient or for some other valid reason.

I am mildly surprised that using a stringstream is less efficient because those C++ gurus definitely seemed to have made execution efficiency a priority in other areas. On the other hand I have also felt that the C++ stream library lacked the elegance displayed by say the STL containers. The shear amount of code required to output formatted data compared to what you can do with printf is daunting.

I am mildly surprised that using a stringstream is less efficient

It's makes perfect sense when you consider what's involved. Underneath iss>> value is a metric shitload of complex interwoven parts, only one of which performs a conversion from a streamed sequence of characters to an integer. On the other hand, strtol is very specialized and can be tuned for the sole purpose of converting a string to an integer.

I have also felt that the C++ stream library lacked the elegance displayed by say the STL containers.

The STL lacks a certain elegance as well, but yes, I agree with you. The stream library's biggest benefit to the programmer is type safety and extensibility (not a small benefit, to be sure). Beyond that it's too verbose for all but the simplest of cases.

commented: Can you translate a metric shitload to American units? :) +4

I am not very experienced in programming, but I think you can do this without using any of the functions like atoi(), etc....
Here's what comes to my mind:

1. Input the 'number' in the form of a string
2. for each character in the string, u can check if the ASCII value lies b/w 48(ASCII for character '0') & 57(ASCII for character '9') till you reach '\0' (if the condition is false at any point, u display the error message)
3. Otherwise, it means the user has input an integer. You can simply convert from a string to an integer by something like this:
multiply the character just before '\0' with 1 and store in an int (say int i=0), then the character 2 places before '\0' with 10 (then simply do i+=result), and so on....also note that before multiplying a character with 10,etc. subtract 48 from it....

I think this is simple enough....

I am not very experienced in programming, but I think you can do this without using any of the functions like atoi(), etc....
Here's what comes to my mind:

1. Input the 'number' in the form of a string
2. for each character in the string, u can check if the ASCII value lies b/w 48(ASCII for character '0') & 57(ASCII for character '9') till you reach '\0' (if the condition is false at any point, u display the error message)
3. Otherwise, it means the user has input an integer. You can simply convert from a string to an integer by something like this:
multiply the character just before '\0' with 1 and store in an int (say int i=0), then the character 2 places before '\0' with 10 (then simply do i+=result), and so on....also note that before multiplying a character with 10,etc. subtract 48 from it....

I think this is simple enough....

Using stringstream is far easier.

1. Load text into stringstream
2. Output text to int type variable
3. Check stringstream fail flag

I am not very experienced in programming, but I think you can do this without using any of the functions like atoi(), etc....

You could do but why re-write code that has already been implemented for you in the library? You are just wasting time and effort that could be put into the program logic proper.

Also what you suggest takes no account of white space but most users would be put out if you rejected there input because they happened to put a space before or after the number.

Using stringstream or strtol takes a lot of the hard work out of the job, which isn't to say that some experienced programmers wouldn't go ahead and do it the way you suggest.

I am not very experienced in programming, but I think you can do this without using any of the functions like atoi(), etc....
Here's what comes to my mind:

1. Input the 'number' in the form of a string
2. for each character in the string, u can check if the ASCII value lies b/w 48(ASCII for character '0') & 57(ASCII for character '9') till you reach '\0' (if the condition is false at any point, u display the error message)
3. Otherwise, it means the user has input an integer. You can simply convert from a string to an integer by something like this:
multiply the character just before '\0' with 1 and store in an int (say int i=0), then the character 2 places before '\0' with 10 (then simply do i+=result), and so on....also note that before multiplying a character with 10,etc. subtract 48 from it....

I think this is simple enough....

Simple and broken. The listed algorithm fails to take signs into account and completely ignores the possibility of integer overflow. Doing this conversion manually is quite a bit harder than a lot of people realize. For example, here's a function that illustrates the work involved in only a partial implementation of the behavior supported by strtol. Notice how only a small portion of the code handles steps 2 and 3 of your algorithm. The rest is for error handling and robustness:

#include <cctype>
#include <cerrno>
#include <climits>

const char *parse_int(const char *s, int *value)
{
    /* Base of the final converted value */
    const unsigned base = 10;

    /* Largest possible value without the least significant digit */
    const unsigned limit = UINT_MAX / base;

    /* Least significant digit from the largest possible value */
    const unsigned top_digit = UINT_MAX % base;

    unsigned overflow = 0; /* True if integer overflow occurs */
    unsigned sign = 0;     /* Final sign of the converted value */

    unsigned temp = 0;     /* The intermediate converted value */
    unsigned n = 0;        /* Count of converted digits */

    /* Save and skip over the sign if present */
    if (*s == '-' || *s == '+')
    {
        sign = *s++ == '-';
    }

    /* Build the intermediate value */
    for (; std::isdigit(*s); s++, n++)
    {
        unsigned digit = *s - '0';

        /*
            This protects *only* the intermediate value
            from overflow. Overflow of the final value
            requires further checks
        */
        overflow = temp > limit || ( temp == limit && digit > top_digit );

        if (overflow)
        {
            break;
        }

        /* Shift-add by the base */
        temp = temp * base + digit;
    }

    if (n > 0)
    {
        /*
            A conversion was made, so now we need to
            deal with overflow and set the final value
        */
        if (overflow
            || (sign && temp > -INT_MIN)
            || (!sign && temp > INT_MAX))
        {
            /*
                The intermediate actually overflowed,
                or converting it to int would overflow.
                Either way it's an error to the caller
            */
            errno = ERANGE;
            temp = sign ? -INT_MIN : INT_MAX;
        }

        *value = sign ? -(int)temp : (int)temp;
    }
    else if (sign)
    {
        /*
            We found a sign and skipped over it. But
            because no conversion was made, we need
            to "unskip" the sign
        */
        --s;
    }

    return s;
}

Oh Well, thanks everyone...you guys are right....I didnt think of so many cases like error on the side of user, overflow, etc....and i understand that it would be stupid to implement it all this all over again...
And thanks Narue, for that program...took me a while to understand what it's doing, but I get the point...

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.