shovon
shovon

Reputation: 1

How to prevent non numeric or non character input or symbols and getting desired output in C

Here's a source code I modified from a youtube tutorial. The purpose of the program is:

it ask your age. If you put 18 or more it ask your gender than print that you can enter dude or m'lady(depends on your gender). If you put your age less than 18 it prints "Nothing to see here!"

I want to make sure that if the input isn't exactly what I ask(only number or only character) it shows "Invalid input". In my program, the first part where the program ask for age, when the input for age is either alphabet or symbol it shows invalid input. But whenever I combine alphabet with number like 18a or 18/ it shows:

"Please enter you gender.(m/f)" "Invalid input."

also, if I input 18 or more and go to the part where the program ask about gender(m/f) it shows Invalid input if I put number or symbol.. But when I combine like m1 or m/ it shows:

"You may enter this website dude."

Can anyone help me about how can I remove this problem?

#include <stdio.h>

#include <conio.h>

int main(void)  {

   char gender; 
   int age=0;

   printf("Please enter your age. \n");

   if(scanf(" %d",&age)!=1)  {
      printf("invalid input. \n");
      return 0;
   }

   if(age>=18)  {

      printf("Please enter your gender.(m/f) \n");

      if(scanf(" %s", &gender) !=1)  {
         printf("Invalid input.\n");

         return 0;
      }

      else if(gender== 'm')  {
         printf("You may enter this website dude.\n");
      }

      else if(gender== 'f')  {
         printf("You may enter this website m'lady.\n");
      }

      else  {
         printf("Invalid input. \n");
         return 0;
      }
   }

   else if(age<18)  {
      printf("Nothing to see here! \n\n");
      return 0;
   }

      return 0;
}

Upvotes: 0

Views: 966

Answers (2)

marian0
marian0

Reputation: 654

If you want to avoid this kind of behavior you should read the entire line for each user option and validate it completely.

To read the entire line you can use scanf(" %[^\n]",str)(*) instead of using %d or %s. Then you can validate user input to check if its exactly what you wanted.

Extra: To validate age you can use: strtol as explained here, and to validate gender I think a simple string comparison will do the trick.

(*) There are several options available to read an entire line in C (fgets for example), and there are also reasons not to use scanf(" %[^\n]",str) (possible buffer overflows) but I tried to show you a solution with the function that you were using, for a nice discussion about this topic take a look at this post.

Upvotes: 2

David C. Rankin
David C. Rankin

Reputation: 84521

The issue you are dealing with has to do with characters that remain in the input buffer (stdin) after you read input with scanf. When you read age, the conversion reads digits from stdin up to the number of bytes that make up and int. Any additional characters following your int remain in the input buffer. (e.g. 18a, scanf reads 18 and a is left in the input buffer after the following:).

int c, age;

if (scanf (" %d", &age) != 1) {
    printf ("invalid age input - conversion failed.\n");
    return 1;
}

(note: you can also perform the same additional character check using strtol for the conversion and checking endptr after your call)

The 'a' left in your input buffer is then taken as input by your gender test. (since it is already in the input buffer, it is automatically read by scanf following the prompt for gender) To check whether all input has been consumed, you can simply check whether the character that remains in the input buffer is '\n' (the result of the user pressing Enter). If the next character in the input buffer is not '\n', then additional characters were entered following age.

if ((c = getchar()) != '\n') {
    printf ("invalid input - additional characters.\n");
    return 1;
}

You can then impose your age restriction after you check for the remaining characters:

if (age < 18)  {
    printf ("Nothing to see here!\n\n");
    return 1;
}

A short example for your age test could be:

#include <stdio.h>

int main (void) {

    int c, age;

    if (scanf (" %d", &age) != 1) {
        printf ("invalid age input - conversion failed.\n");
        return 1;
    }
    if ((c = getchar()) != '\n') {
        printf ("invalid input - additional characters.\n");
        return 1;
    }

    if (age < 18)  {
        printf ("Nothing to see here!\n\n");
        return 1;
    }

    printf ("\n age: %d\n\n", age);

    return 0;
}

Examples

$ ./bin/age
18

 age: 18

$ ./bin/age
17
Nothing to see here!

$ ./bin/age
18a
invalid input - additional characters.

$ ./bin/age
aa
invalid age input - conversion failed.

Look it over and let me know if you have any questions.

Upvotes: 0

Related Questions