3

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?

pb2q
  • 58,613
  • 19
  • 146
  • 147
rajesh6115
  • 705
  • 9
  • 21

2 Answers2

4

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.

pb2q
  • 58,613
  • 19
  • 146
  • 147
  • this works fine but is C library providing some facility to clear the input buffer.like they provide facility like fflush() for output buffer. – rajesh6115 Aug 04 '12 at 02:44
  • No there is no standard facility to clear the input buffer (though some implementations might provide it). Just read the input, e.g. using fgets(). It's just a function call like fflush() would have been. – nos Aug 04 '12 at 02:48
  • 1
    `int c; do c = getchar(); while (c != EOF && c != '\n');` is my preferred way to read and discard input; it has the advantages of not needing a scratch buffer (only the one `int`) and coping with garbage input of any length. – zwol Jun 27 '13 at 23:06
1

That is by design.

Don't use break, use continue.

Steve Wellens
  • 20,506
  • 2
  • 28
  • 69
  • I want to know why not wait for my input further and how can i manage error so that i can take input again. – rajesh6115 Aug 04 '12 at 02:29
  • Why should it wait? When you hit Enter, you are saying read the string. If there is an error YOU need to decide if you want to try again or abort the program. – Steve Wellens Aug 04 '12 at 02:33