Reputation: 51946
I have a program where I want the input integer to be between 2 and 64 inclusive, so I put scanf
inside a do { ... } while
loop. Here's the code I initially tested:
int initialBase;
do {
printf("Initial base: ");
scanf("%i", &initialBase);
} while (initialBase < 2 || initialBase > 64);
The problem is whenever the input is not a valid integer, it just outputs the printf
statement indefinitely and no longer prompts for user input, instantly flooding the console. Why is that happening and what's a better way of reading input that satisfies the conditions I want?
Upvotes: 2
Views: 190
Reputation: 53016
When scanf()
fails, the argument is not automatically initialized, and uninitialized values could be any value, so it might be less than 2
or greater than 64
no one knows.
Try this
int initialBase;
/* some default value would be good. */
initialBase = 2;
do {
printf("Initial base: ");
if (scanf("%i", &initialBase) != 1)
break;
} while ((initialBase < 2) || (initialBase > 64));
the check will break out of the loop if you input something that is not a number, the initialiazation of initialBase
is just a good habit which in your case could have prevented the behavior you describe, but in this case it's there to prevent accessing an uninitialized value after the while
loop.
The reason the loop didn't stop, was because scanf()
leaves some characters in the input stream when they are not matched, and calling scanf()
again while those characters are still there will make scanf()
keep waiting for valid input, but returning immediatly with the currently invalid input that is in the stream, if you want to keep reading, try reading characters from the stream until a '\n'
is found, this way
int initialBase;
initialBase = 0;
do {
printf("Initial base: ");
if (scanf("%i", &initialBase) != 1)
{
while (fgetc(stdin) != '\n');
continue;
}
} while ((initialBase < 2) || (initialBase > 64));
Upvotes: 3