Advertisement
If you have a new account but are having problems posting or verifying your account, please email us on hello@boards.ie for help. Thanks :)
Hello all! Please ensure that you are posting a new thread or question in the appropriate forum. The Feedback forum is overwhelmed with questions that are having to be moved elsewhere. If you need help to verify your account contact hello@boards.ie

C++ - Ensure input in numeric

Options
  • 21-09-2010 7:57pm
    #1
    Registered Users Posts: 7,869 ✭✭✭


    Hi folks,

    I'm just making a simple little app for practice and I'm validating input.

    The input has to be numeric, else it crashes. I've declared the variable as an int type, but obviously when I use "cin >> " at the command line, it'll take any input and send it into my loop on the next line, which in turn, crashes the app!

    So, is there a way I can check the input?

    For example,
    cin >> intvar
    
    while intvar != number
    then re-ask for input until finally a number is entered
    .
    .
    .
    do more stuff
    

    Any idea how I can do this? I tried that "isdigit()" function but that needs a char, ie isdigit(char). I need some other way of doing this. Maybe an ascii range I can use?

    Cheers


Comments

  • Registered Users Posts: 428 ✭✭Joneser


    I'm sure there is a much more efficient way to do this as I haven't used C++ in a while but maybe you could split the input string into its individual characters, and if isDigit() is true for all of them, then accept the input


  • Registered Users Posts: 26,579 ✭✭✭✭Creamy Goodness


    why not read in the input as a char variable then use isDigit() on that char var. then if that's true you can cast the char as an int?

    otherwise, itoa() http://www.cplusplus.com/reference/clibrary/cstdlib/itoa/ and check if the value is between the range of 48-57 (0-9 in ascii)


  • Registered Users Posts: 7,869 ✭✭✭The_B_Man


    itoa() might be OK, except what happens if a number higher than 9 is entered?

    changing the var to char might have to be the only way. I'll see what happens anyway.

    EDIT: That didnt work with the char. Need to input a string from cin. Will try that instead.


  • Moderators, Education Moderators, Home & Garden Moderators Posts: 8,173 Mod ✭✭✭✭Jonathan


    Can I ask what you are doing that causes the app to crash in the loop?

    INTs and CHARs are essentially the same thing, both 1 byte long.


    Could you do some casting to avoid the app crashing?

    EDIT: you could input your variables into a char*, and then use something like the code below to convert from ASCII numbers to an unsigned int.
    // convert two ASCII numbers from the input array to a single byte
    unsigned int digitToByte(char x,char y){
      return (unsigned int) ((buffer[x]&0x0F)*0xA+(buffer[y]&0x0F));
    }
    


  • Registered Users Posts: 3,287 ✭✭✭padraig_f




  • Advertisement
  • Registered Users Posts: 7,869 ✭✭✭The_B_Man


    What I've done is declared a char array[], then read the input into it. (notice the []'s are empty).

    I've then made a for loop to run thru it and did a !isdigit() on it to check for a char. If it finds even 1 char, it'll throw up a "Please re-enter" message.

    Once everything is validated, I used int=atoi(char[]) which gives it the int value.

    Now, I noticed the array[] should have a defined size so put in a size, eg 3. Now its buggered somehow! If i enter a valid input, it still throws up the error, so somehow that change has messed up my logic! :(


  • Registered Users Posts: 428 ✭✭Joneser


    Could you perhaps set the size of the array to the .length of the user input?


  • Closed Accounts Posts: 5,082 ✭✭✭Pygmalion


    What you could do is read in one char at a time until the end of line (a '\n' character signifies user pressing enter) and convert it to a number as you go.

    Code (not actually compiling this so may need modifications before it actually runs/works as expected)
    char temp;
    int num = 0;
    
    while ((temp = getChar()) != '\n') {
        if (isDigit(temp)) {
            num *= 10;
            num += (temp - '0');
        }
        else {
            //Non-digit found. Do whatever here, but make sure you keep reading up until the '\n' character so when you ask again it doesn't continue reading from where it left off.
        }
    }
    
    This (should) basically do what atoi() does (but probably not as well, and doesn't handle negative numbers :P) but since it just reads the number straight in from keyboard it means you don't have to worry about storing the input somewhere, or deciding what length it should be.

    Maybe I'm misunderstanding what you want to do.
    Hopefully code is self-explanatory, feel free to ask if it's not.

    If you'd rather read it all in at once then know that an integer (on 32-bit systems) will never be more than 10 digits so you could use a a char array long enough for that, but that has two problems.
    1: If you compile on 64-bit systems the compiler might (but probably won't tbh) use a 64-bit integer, which could be up to 20 digits.
    2: If the user enters longer than 10 digits it could cause problems/crashes, my one won't work properly for larger integers but it'll just give a wrong answer instead of crashing.
    But tbh if this is a practise app no-one cares above the above :P.


  • Registered Users Posts: 2,082 ✭✭✭Tobias Greeshman


    You can do a check based on the good() method of the istream class (the stackoverflow link mentions this as well). If you enter any alphabetic character for the number then the good() check will fail, all numeric checks will pass. So for example 0.5 will be accepted and store only the whole part of the number.
    #include <iostream>
    
    using namespace std;
    
    int main(void)
    {
        int in;
    
        cin >> in;
        if (cin.good())
            cout << "Valid integer: " << in << endl;
        else
            cout << "Bad integer: " << in << endl;
    
        return 0;
    }
    


Advertisement