Filtered scanf causing infinite loop

2019-05-30 10:12发布

问题:

I've got in one program filtered input via scanf. I want read only numbers and big letters + spaces.

Recently I was trying to do something like that, and it stuck in an infinite loop, still printing only first input. I know about fgets(), but I know this worked. I can't find out where the problem is. Here's simplified situation; what is happening to me?

#include <stdio.h>
#include <string.h>

int main()
{
  char str[21];

  do
  {
    scanf("%20[0-9A-Z ]", str);
    printf("%s\n", str);
  } while(strcmp("END", str) != 0);

  return 0;
}

EDIT: I forgot to mention, input is valid, for input: "HELLO" program stuck...and scanf return 1 only for first input, for others returning 0. And I also tried fflush(stdin), after reading...

回答1:

Your scanf accepts only digits, upper case letters (latin alphabet) and spaces,

scanf("%20[0-9A-Z ]", str);

so when you enter anything else, scanf fails to assign input to str, and the offending input remains in the input buffer. You need to check whether the scan succeeded and clear the input buffer on failure.

And since in particular newlines are not among the valid input tokens, you need to clear the input buffer until the next newline anyway if the input comes from e.g. the keyboard and not a newline-free input stream.

int c;
do
{
  scanf("%20[0-9A-Z ]", str);
  printf("%s\n", str);
  while((c = getchar()) != '\n' && c != EOF); // clear input buffer
} while(c != EOF && strcmp("END", str) != 0);


回答2:

Depends on the input a bit - but you could check that scanf worked - it will return the number of matched expressions - so should be 1 in this case. If its 0 - its not matching the input, so it may stick where it is.



标签: c scanf