why does scanf not wait for user input after it fa

2020-02-07 04:55发布

问题:

I face problem in my code below. When I enter any integer, that is (0-9), then it is OK. But when I enter some other characters like A, B or any other letter scanf() fails. Then it doesn't wait for any further input.

I've attached a code snippet for this. I highly require error handling using only the C standard library.

#include <stdio.h>

int main()
{
    int choice;
    while(1)
    {
        printf("Enter your choice: ");
        if(0 == scanf("%d", &choice))
          {
              printf("Some error occured\n");
              //break;/*I did not want to break this loop as I use this to show menu*/
          }

        switch(choice)
         {
                      case 0:printf("Case 0\n");break;
                      case 1:printf("Case 1\n");break;
                      case 2:printf("Case 2\n");break;
                      case 3:printf("Case 3\n");break;
                      case 4:printf("Case 4\n");break;
                      case 5:printf("Case 5\n");break;
                      case 6:printf("Case 6\n");break;
                      case 7:printf("Case 7\n");break;
                      case 8:printf("Case 8\n");break;
                      case 9:printf("Case 9\n");break;
                      default:printf("Default case\n");break;

         }
    }
}

Question more clearly is: why doesn't it wait after failure?

回答1:

With scanf, if the input given doesn't match the format specification, then the input isn't consumed and remains in the input buffer. In other words, the character that doesn't match is never read.

So when you type, e.g. an a character, your code will loop indefinitely as scanf continues to fail on the same character.

When scanf returns an error, you need to get rid of the offending character(s).

You can't know how many characters will be typed, but one simple way to consume any offending characters is to try and read a string when scanf fails:

char junkChars[256];

printf("Enter your choice: ");
if (scanf("%d", &choice) == 0)
{
    printf("Some error occured\n");
    scanf("%s", junkChars);
}

This will clear the input buffer, but relies on an upper-bound. If the user types more than 256 characters, the scanf will continue to consume them on the next iteration(s).

Clearly this is an ugly solution, but scanf isn't really a great input mechanism for this reason. Better to use fgets to get the input line as a string, then control the parsing of that string yourself.



回答2:

That is by design.

Don't use break, use continue.



标签: c scanf