#1
  1. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Oct 2013
    Posts
    3
    Rep Power
    0

    Handling incorrect data types when using scanf


    Morning everybody.

    I'm currently trying to create a basic menu for the start point of a little program, and while I understand the basics of C I've never been taught very much and so am past the end of my knowledge base on this problem.

    Code:
    void menu()
    {
        int menuchoice;
    
        scanf("%int", &menuchoice);
    
    if (menuchoice < 1 || menuchoice > 4)
        {
        printf("Please enter a valid choice\n\n");
        menu();
        }
    else
    
        switch (menuchoice)
    
        {
            case 1:
                {
                    option1();
                    break;
                }
            case 2:
                {
                    option2();
                    break;
                }
            case 3:
                {
                    option3();
                    break;
                }
            case 4:
                {
                    option4();
                    break;
                }
        }
    
    }
    That's what I've got for the menu, just a simple little thing to scan in an integer input and run the relevant function depending on what the input is.

    What I'm needing to do is have it running so that if anything other than an integer is entered it simply asks for a new input, but I have no idea how to do that, hence why at the moment it's simply checking that if an integer is entered it falls within the defined range.

    Could somebody please give me some pointers to get me going in the right direction on this.

    Thanks.
  2. #2
  3. Contributing User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Sep 2013
    Location
    Saint-Petersburg, Russia
    Posts
    236
    Rep Power
    28
    Simply input the string instead of int (%s instead of %d in the scanf or simply gets or fgets).

    Checking whether string contains a number is a bit painful in C/C++ - you can either iterate through symbols and check that each of them lies between '0' and '9' - and if so, use 'atoi'.

    Or you can utilize 'strtol' function.

    "%int"
    By the way are you sure this is correct?
  4. #3
  5. Contributing User

    Join Date
    Aug 2003
    Location
    UK
    Posts
    5,110
    Rep Power
    1803
    Your code is unnecessarily and dangerously recursive. Recursion is not iteration. menu() should not call menu(). When you finally get the user to enter a valid value after perhaps several invalid ones, what do you think will happen when the most deeply nested menu() call returns?

    Recursion should almost never be used and certainly not for this purpose.


    There are many ways to solve your user input problem, here's one:

    Look at what scanf() returns - it is useful in this case.

    C Code:
    void menu()
    {
        int menuchoice = 0 ;
     
        while( menuchoice == 0 )
        {
            int check ;
            printf( "Enter choice: " ) ;
            check = scanf( "%d", &menuchoice ) ;
            if( check == 0 || menuchoice < 1 || menuchoice > 4 )
            {
                menuchoice = 0 ;
                printf("Please enter a valid choice\n\n");
            }
        }
     
        // remove any characters after the number up-to and 
        // including the inevitable newline
        while( getchar() != '\n' )
        {
            // do nothing
        }
     
        switch (menuchoice)
        {
            ...
        }
    }

    Note also that when you use the %i format specifier (not %int BTW), only the digit characters are consumed, any remaining input (including the necessary newline) will remain buffered and may cause problems at the next input statement encountered. You need to explicitly flush to the end of the line.

    Another issue is that %i accepts input in decimal, octal and hexadecimal, which is seldom what you want, generally you would use %d for this purpose.
    Last edited by clifford; October 16th, 2013 at 11:53 AM.

IMN logo majestic logo threadwatch logo seochat tools logo