russ0
russ0

Reputation: 63

Using while (scanf(...)==0) properly

I have a question regarding the use of scanf with the invalid return. Here is a fragment of code I am testing:

printf("Please enter a number\n");
while (scanf("%d",&number)==0)
{
    printf("Try again.\n");
    scanf("%d",&number);
}

My reasoning suggests that if an invalid type is used, my second scanf should ask again and test the new entered value. However, this is not the case and the Try again message never stops printing so I have to terminate it manually. I am not sure why this is happening. I don't want to have to use the scanf before the while loop if possible although I know this is a possible workaround. I would appreciate any help on this matter. Thanks.

Upvotes: 1

Views: 6155

Answers (2)

chux
chux

Reputation: 153338

scanf() may return an EOF to indicate an input failure.

"The scanf function returns the value of the macro EOF if an input failure occurs before the first conversion (if any) has completed. Otherwise, the scanf function returns the number of input items assigned, which can be fewer than provided for, or even zero, in the event of an early matching failure." C11 7.21.6.4

The use of scanf("%d", ... after a failed scanf("%d", ... only result in an infinite loop as each scanf() is trying to consume a non-digit, no-space and failing. To get past the problem, the offending data must be consumed.

printf("Please enter a number\n");
int number;
int Count;
while ((Count = scanf("%d",&number)) != 1) {
  if (Count < 0) {
    exit(1); // No more input possible
  }
  // Some char is preventing scanf() from reading an int
  scanf("%*c");  // Get it and throw away
  printf("Try again.\n");
}
printf("number = %d\n", number);

Upvotes: 1

Potatoswatter
Potatoswatter

Reputation: 137770

scanf does not return an error code. It returns the number of conversions successfully performed.

As for the endless loop, it doesn't consume the input that can't be converted. So it's repeatedly trying to match the same string as a number. Try using fgets to discard the offending input.

Upvotes: 4

Related Questions