You write a C program that asks for a number. You test it, type abc by accident, and the program goes crazy: it prints the same question again and again, forever, and you have to close the terminal. This is one of the first real bugs most people hit in C. The good news is that the cause is simple and the fix is about five lines.
The Problem: scanf Loops Forever
Here is a typical program that keeps asking until it gets a valid age:
#include <stdio.h>
int main(void) {
int age = -1;
while (age < 0) {
printf("Enter your age: ");
scanf("%d", &age);
}
printf("You are %d years old.\n", age);
return 0;
}
Type 20 and it works. Type abc and “Enter your age:” fills the screen.
Why It Happens
When you type something and press Enter, it goes into the input buffer, a waiting area that scanf reads from. scanf("%d", ...) looks at the start of the buffer and tries to read a number.
If it finds abc, it can’t turn that into a number, so it gives up. But it doesn’t remove abc from the buffer. The loop runs again, scanf looks at the buffer, finds the same abc, fails again, and so on forever. It never waits for you to type, because there’s still something in the buffer.
Your program also has no idea it failed, because it never asked. scanf tells you how many values it read successfully through its return value, and the code above ignores it.
The Fix: Check the Return Value and Clear the Bad Input
Two changes fix it. First, check that scanf returned 1 (one number read). Second, when it didn’t, throw away everything up to the end of the line so the next try starts clean:
#include <stdio.h>
int main(void) {
int age;
printf("Enter your age: ");
while (scanf("%d", &age) != 1) {
int c;
while ((c = getchar()) != '\n' && c != EOF) {
/* throw away the bad input */
}
if (c == EOF) {
return 1; /* input closed, nothing more to read */
}
printf("That's not a number. Try again: ");
}
printf("You are %d years old.\n", age);
return 0;
}
The inner while loop reads one character at a time with getchar() until it reaches the newline from the Enter key. That empties the buffer, so the next scanf waits for new input. The EOF check stops the program cleanly if the input ends, for example when someone presses Ctrl+Z on Windows or Ctrl+D on Linux and Mac.
Other Input Traps in C
While you’re fixing input, watch for these too:
Forgetting the &:
scanf("%d", age)passes the value instead of the address, which usually crashes the program. It needs&age.Names with spaces:
scanf("%s", name)stops at the first space, so “Emre Guzel” becomes “Emre”. Usefgets(name, sizeof name, stdin)instead. It reads the whole line and can’t overflow the array.fgets keeps the newline: remove it with
name[strcspn(name, "\n")] = '\0';(include<string.h>).Never use gets(): it has no length limit and was removed from C in C11.
Try It Yourself
Run both versions and type abc, then 12abc. The second one is interesting: scanf reads 12 and leaves abc behind, so a later scanf in your program would fail. If that matters, read the whole line with fgets and convert it with strtol, which tells you exactly where the number ended.
For the full picture, with practice programs for the area of a rectangle and a circle and using input with if and else, read my complete guide to user input in C. If you’re just starting out, begin with the introduction to C programming.
Have you hit this infinite-loop bug before? Tell me what you typed in the comments, and I’ll help you fix it.
Originally published on my blog. I post new C, Python and AI-agent guides there regularly.
Top comments (0)