Home > Software design >  How to go back to the beginning of a case if the conditions aren't met
How to go back to the beginning of a case if the conditions aren't met

Time:11-17

`

switch(selectedOption){
  case 'B':
    printf("Please enter the first number\n");
    if (scanf("%f", &firstNumber) == 1){
       printf("Is a valid number\n");
    }
    else{
       printf("Is not a valid number\n");
    }
}

`

I have a school assignment where I have to program a calculator. One of the requirements is to ask for the user to input another number if they for example input a character instead of a number. I'm not sure how to go about this and I looked everywhere and no solutions made sense. I would appreciate it a ton if someone could help me out with this problem.

CodePudding user response:

The simple answer is to loop until valid input has been read (assuming the input comes from an interactive agent such as a person sat at a terminal).

The following will not work:

switch(selectedOption){
  case 'B':
    while (1) {
      printf("Please enter the first number\n");
      if (scanf("%f", &firstNumber) == 1){
         printf("Is a valid number\n");
         break;
      }
      else{
         printf("Is not a valid number\n");
      }
    }
    /* ... */
    break;
}

The problem is that scanf will stop reading input when it sees a character that is not part of the number, and will push that character back onto the stream (c.f. ungetc). For example, if the input is -foo, scanf will read the spaces, then the - (which could be part of the number), then the f which is not part of the number. The f will be pushed back onto the stream and scanf will return 0. On the next iteration of the while loop, scanf will read the f, push it back onto the stream and return 0. Loop ad infinitum, et ultra.

To break the infinite loop, the code needs to read something from the stream and discard it. One option is to read and discard the next word by calling scanf("%*s");, or discard the next word and the following whitespace character by calling scanf("%*s%*c");, or discard the remainder of the line and the newline by calling scanf("%*[^\n]%*c");. E.g.:

switch(selectedOption){
  case 'B':
    while (1) {
      printf("Please enter the first number\n");
      if (scanf("%f", &firstNumber) == 1){
         printf("Is a valid number\n");
         break;
      }
      else{
         printf("Is not a valid number\n");
         scanf("%*s");
      }
    }
    /* ... */
    break;
}

Note that input such as 42foo will be considered valid by the above code. scanf will push the f back onto the stream and return 1 because it has read a valid number 42. You may want to read the next character and check that it makes sense. You can always push at least one character back onto the stream by calling ungetc(ch, stdin); so that it can be re-read later.

CodePudding user response:

You do not need switch - case. You just need to do:

while (true) {
    char number = 0;
    scanf_s("%c", &number);
    if (number >= '0' && number <= '9') break;
    else printf("Is not a valid number\n");
}
  • Related