Extn3389
Extn3389

Reputation: 48

Infinite looping when Switch case is given wrong input

I have a very simple code segment where there is a do while loop with a switch case which goes as follows:

do {
    printf("Enter Choice\n");
    scanf("%d", &choice);
    switch(choice) {
          case 1: printf("1 selected");
                  break;
          case 2: printf("exit");
                  break;
          default: printf("wrong input");
                  break;
    }
} while (choice != 2);

In this piece of code if by accident I enter a character instead of a number the program goes haywire looping indefinitely and doesnt even take the input. I know this can be corrected if I insert

if(isdigit(choice))

before getting into switch case. But my question is why does it happen in the first place.

Shouldn't it go to default case and ask for input again?

Upvotes: 0

Views: 2342

Answers (3)

Vishal
Vishal

Reputation: 1

I tried if(isdigit(choice)) but problem remain as it is. This issue is related with buffer if datatype of input doesnt match with format specifier in scanf then input is not consume by scanf and remain in buffer.

To solve this issue I tried fflush(stdin) which works fine for c compiler in windows but not working on linux ,sorry I dont know the reason why fflush(stdin) not working on linux.

I also tried getchar() which work fine on windows and linux, I put getchar() at end of statement inside loop .

 do 
    {
       printf("Enter Choice\n");
    scanf("%d", &choice);
        switch(choice) {
              case 1: printf("1 selected");
                      break;
              case 2: printf("exit");
                      break;
              default: printf("wrong input");
                      break;
        }

    getchar();
    } while (choice != 2);

Upvotes: 0

cnicutar
cnicutar

Reputation: 182619

If scanf can't match input with the format specifier, it leaves it in the buffer. So the next time around it still won't match and so on. In other words, it doesn't eat what it can't match. You must check the value returned by scanf, the number of matched items, to make sure the input was expected.

Alternatively, to skip unwanted stuff, you could try (untested):

scanf("%*[^0-9]%d", &choice);

This should discard anything that's not a digit before trying to read a decimal integer.

Upvotes: 5

Ed Heal
Ed Heal

Reputation: 59997

Please checkout the scanf manual page.

If the next thing in the input is not a number in this case it does not consume it.

You need to check the return value from scanf and if it is zero, consume the next character and try again (or perhaps until end of line is reached).

Upvotes: 1

Related Questions