user2781018
user2781018

Reputation:

How to ensure user-input data is an integer

I am new to C, but I know C#. In C#, I could use TryParse to ensure that the user typed in the correct datatype.

Here is the basic code I have for C:

int shallowDepth;

do
{
    printf ("\nEnter a depth for the shallow end between 2-5 feet: ");
    scanf ("%d", &shallowDepth);

    if (shallowDepth < 2 || shallowDepth > 5)
    {
        printf("\nThe depth of the shallow end must be between 2-5 feet.");
    }
}
while (shallowDepth < 2 || shallowDepth > 5);

The problem is if I type characters, such as "asdf", the program goes crazy and repeatedly says "Enter a depth for the shallow end between 2-5 feet: ". I'm not sure why this is exactly happening, but it has to be because it expects an int and I'm passing characters.

So how do I verify that the user inputted data is of int type before trying to store it in a variable? Thanks.

Upvotes: 0

Views: 126

Answers (3)

BLUEPIXY
BLUEPIXY

Reputation: 40155

int shallowDepth;
int invalid;
do {
    int stat;
    invalid = 0;
    printf ("\nEnter a depth for the shallow end between 2-5 feet: ");
    stat = scanf ("%d", &shallowDepth);

    if(stat != 1){
        invalid = 1;
        while(getchar() != '\n');//clear stdin
    } else if (shallowDepth < 2 || shallowDepth > 5){
        invalid = 1;
        printf("\nThe depth of the shallow end must be between 2-5 feet.");
    }
}while (invalid);

Upvotes: 0

cnicutar
cnicutar

Reputation: 182734

This is happening because with %d scanf will refuse to touch anything that does not look like a number and leaves the text in the buffer. The next time around it will again reach the same text and so on.

I recommend that you ditch scanf for now and try something like fgets and then one of the functions in the strtoXXX family such as strtoul or strtoumax. These functions have a well-defined way of reporting errors and you can easily prompt the user for more text.


For example you could do:

char str[LENGTH];
long x;
if (!fgets(str, sizeof str, stdin)) {
    /* Early EOF or error. Either way, bail. */
}

x = strtol(line, NULL, 10);

At this point you could use your number, but be aware that:

  • You can specify a pointer for strtol to fill and it will point to the first unacceptable character
  • If the result cannot be represented as a long then strtol will set errno = ERANGE. If you plan to test for this you must set errno = 0 before the strtol

Upvotes: 3

Juri Robl
Juri Robl

Reputation: 5746

If you want to use scanf you can't test it before. But you don't need too!

In your code if the user doesn't enter a number (or something that starts with a number), scanf returns 0, because it returns the number of parameters it could read. So you need to check the return value of scanf to check if anything could be read. Second, you need to remove everything that's still in the puffer. You can use something like this for that:

while(getchar()!='\n');

If you want to handle files as well, you should catch EOF there, too.

Upvotes: 0

Related Questions