0

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;
    }

  }
3
  • It's because the non-numeral d remains in the input buffer, and will stay there no matter how many times you try to read int. I suggest reading with fgets into a string and then extracting the int with sscanf. Commented Mar 9, 2016 at 18:00
  • @Weather Vane: I see it's still out there because of this infinite loop but scanf reads from stdin? it waits for input from stdi. the cppreference mentions data from the a variety of sources. so how use scanf to accept only stdin and ignore buffer, without flush 'sscanf" ..? Commented Mar 9, 2016 at 18:09
  • You are reading an int. The scan stops at the first non-numeric character, which remains in the input buffer. scanf usually reads stdin through a buffer. I believe it is possible to disable the buffer, but it's a perverse way of handling the situation. The guys who designed the OS did it for a reason. Commented Mar 9, 2016 at 18:16

1 Answer 1

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
}
Sign up to request clarification or add additional context in comments.

1 Comment

I don't understand why EOF. Normally I do while (char c = getchar() != '\0'); to clear a buffer, and then you say // Make it large enough but in this case age ok, and sometimes we don't know how large it can become?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.