Home > Net >  User input error when asking for a digit (switch case) C
User input error when asking for a digit (switch case) C

Time:01-24

For this program i'm asking the user to enter a digit and it returns the digit you've entered but in another language. I'm using a switch case to utilize this and for user input errors when typing a letter instead of the digits 0-9 it defaults to invalid user input, however, when I enter 10, 11, or 12 which is outside the range it prints out isa which is number 1 which shouldn't be happening. How do I make it so that if the user enters an invalid number outside the 0-9 range it also says invalid input?

Here's the code

#include <stdio.h>

int main(void) {
  printf("This program will display the Filipino(Tagalog) word for a digit of your choice.\n");
  printf("Enter a digit 0-9: ");
  int digit = getchar();
  switch(digit) {
    case '0' :
      printf("wala\n");
      break;
    case '1' :
      printf("isá\n");
      break;
    case '2' :
      printf("dalawá\n");
      break;
    case '3' :
      printf("tatló\n");
      break;
    case '4' :
      printf("ápat\n");
      break;
    case '5' :
      printf("limá\n");
      break;
    case '6' :
      printf("anim\n");
      break;
    case '7' :
      printf("pitó\n");
      break;
    case '8' :
      printf("waló\n");
      break;
    case '9' :
      printf("siyám\n");
      break;
    default :
      printf("Invalid input\n");
  }
  return 0;
}

Thank you!

CodePudding user response:

It's because getchar() only retrieves one character from standard input. It doesn't read in an entire integer. When you pass 10, 11 or 12, your code is actually reading in 1 and leaving the second digit in standard input.

You have at least a couple of options:

  1. Read in an integer from stdin, using scanf() instead of getchar(). Take a look at How can I get an int from stdio in C?, this should provide you all the information you need to do it this way, if you choose to do it. You will need to modify your switch-cases to use integer literals rather than character literals for the digits you want to switch on.
  2. Alternatively, you could instead read in an entire line of input with fgets() and check to make sure it only contains 1 character, then retrieve that first character to use in the switch. This is in keeping with your intent of wanting to switch on digits, and also additionally will not fail if you pass a non-integer input to stdin, whereas if using scanf(), you need to check the return code to make sure malformed input was not given.
    I recommend this approach because it is easier to make it fault-tolerant than the other one.

CodePudding user response:

Echoing what the previous answerer said, getchar reads only one character from the standard input stream. Once it gets a character, it assigns it to digit. getchar and friends return a value of type int in order to be able to return the EOF value (which is out of char range) so you know when your stream ends. So really digit is a character, just with int type for that extra little bit of range.

I'll add that getchar will leave behind any characters left behind on the input stream that were not used. If you're using this program on the command line and press 3 followed by the enter key in order to get the output tatló, the enter key will leave a '\n' character (in Linux--I'm honestly not sure if it will be '\n' or '\r' in Windows) on the standard input stream, which the first getchar does not consume. So you could check this value with another call to getchar. Something like this:

...
printf("Enter a digit 0-9: ");
int digit = getchar();
if(getchar() != '\n') {
  /*The user typed something after the initial digit, do something, like maybe assigning an invalid value to `digit`*/
  digit = 'a';
}
switch(digit) {
  ...

The second call to getchar will return '\n' if your user entered just a single character; otherwise it will return the second character that the user entered.

This is a suitable solution to parsing a number from user input if you never intend to parse multi-digit numbers.

  • Related