C scanf in a loop with invalid input

2020-08-01 19:58发布

问题:

I have to do this if statement , or it turns in an infinite loop if some invalid input like "17d" is set. Why ? I think something with buffer but scanf reads from stdin not from stream?

  int age;

  while (age != 0) {
    printf("How old are you? ");

    if(scanf("%d", &age) > 0) {
      printf("You are %d years old!\n", age);  
    } else {
      break;
    }

  }

回答1:

When scanf does not succeed, it leaves the input in the stream. You need to ignore the rest of the line and ask the user to provide the input again. You can add a function like:

void ignoreRestOfLine(FILE* fp)
{
   int c;
   while ( (c = fgetc(fp)) != EOF && c != '\n');
}

and call it from main:

if(scanf("%d", &age) > 0) {
  printf("You are %d years old!\n", age);  
} else {
  // Ignore rest of the line and continue with the loop.
  ignoreRestOfLine(stdin);
}

Another option is to read the data a line at a time and use sscanf to extract the number from the line.

char line[100]; // Make it large enough
while (age != 0)
{
   printf("How old are you? ");

   if ( fgets(line, sizeof(line), stdin) == NULL )
   {
      // Problem reading a line of text.
      // Deal with it.
      break;
   }
   else
   {
      if(sscanf(line, "%d", &age) > 0)
      {
         printf("You are %d years old!\n", age);  
      }
   }

   // Try to read again
}