Menu

While Loop in C: Syntax, Examples, and Common Mistakes

How the C while loop repeats until a condition changes - the condition-first rule, sentinel loops, reading input until EOF, while(1), and converting between for and while.

This page includes runnable editors - edit, run, and see output instantly.

Repeating Without a Count

A for loop is the right tool when you know - or can compute - how many passes you need. Plenty of work does not come with a count. Read every line of a file until it ends. Keep asking for a password until it is right. Halve a number until it reaches 1. For these, the question is not "how many times" but "until when", and that is exactly what while expresses.

Nobody computed "seven" in advance. The loop simply keeps going while the condition holds.

Syntax and the Condition-First Rule

while (condition) {
    // body - runs while the condition is nonzero
}

The condition is tested before every pass, including the first. Three consequences:

  • A loop whose condition starts false runs zero times. while (0) { ... } never executes the body.
  • Whatever the condition tests must be initialised before the loop, or you are testing a garbage value.
  • Something in the body must eventually make the condition false, or the loop never ends.

Like if, the parentheses are required and there is no semicolon after them. That stray semicolon is the loop version of the same bug:

/* BUG: the empty statement is the body - this spins forever */
while (i < 10);
{
    printf("%d\n", i);
    i++;
}

i is never incremented, so the condition never changes. gcc -Wall flags the empty body.

C's truthiness rule applies here exactly as it does in if/else: the loop continues while the expression is nonzero, and stops when it is zero.

The Standard Shape: Initialise, Test, Update

Almost every correct while loop has three pieces spread across three places:

That is the same three parts a for header holds, just not gathered in one line. Which is the honest answer to "for or while?": if all three pieces are about one counter, a for puts them where a reader can check them together. If the update is scattered through a long body, or the condition is about something other than a count, while is the clearer form.

Forgetting piece 3 is the while-loop bug. If a loop hangs, the first thing to check is whether the body actually changes what the condition reads.

Sentinel Loops

A sentinel is a special value that means "stop". Sum numbers until the user enters 0:

The 99 after the 0 is never reached - the sentinel ended the loop. Note that the count of numbers is never known in advance, which is precisely why this is a while.

C strings work the same way: they end with a '\0' sentinel, so walking one is a textbook while:

Reading Input Until EOF

The most common real-world while reads input until there is none. The rule is to test the return value of the input function, not the value it stored.

getchar returns the next character, or the constant EOF when input runs out:

Two details that matter. c is an int because EOF is a negative value that does not fit in a char on many systems - declaring it char can make the comparison never succeed. And the assignment sits inside the condition: (c = getchar()) != EOF reads a character, stores it, and compares in one step. The inner parentheses are required, because != binds tighter than =; without them you would store the comparison's result in c. This is one of the few places where assignment inside a condition is idiomatic rather than a bug.

The same shape works with scanf, whose return value is the number of items successfully converted:

int n;
while (scanf("%d", &n) == 1) {
    /* n holds a valid number */
}

The loop ends at end-of-file and on the first input that is not a number, which is usually what you want.

What you should not write is while (!feof(f)). feof reports whether a read has already failed, so it is still false when you are sitting on the last item, the loop body runs once more, and the read fails - processing stale data. Test the read itself.

while (1) and break

Sometimes the exit condition is only known in the middle of the body - after reading, but before processing. The idiomatic answer is an intentionally infinite loop with an explicit exit:

while (1) is always true, so the only way out is break (or return, or exit). You will see for (;;) used for the same purpose; they compile to the same thing, and which one a codebase prefers is a style question.

Use this shape when the exit test genuinely belongs mid-body. When the test fits naturally at the top, put it in the condition where a reader can see it - a while (1) whose only break is the first statement is just a condition in disguise.

Converting Between for and while

Any for loop can be written as a while loop and the other way around. The mapping is mechanical:

/* for */                          /* equivalent while */
for (init; cond; update) {         init;
    body;                          while (cond) {
}                                      body;
                                       update;
                                   }

So these two print the same thing:

The one place the equivalence leaks is continue. In a for loop, continue jumps to the update in the header, so the counter still advances. In the while version, continue jumps straight back to the condition and skips the i++ at the end of the body - an instant infinite loop:

/* BUG: continue skips i++, so the loop spins forever on the first even number */
int i = 0;
while (i < 10) {
    if (i % 2 == 0) {
        continue;
    }
    printf("%d ", i);
    i++;
}

If a while loop uses continue, make sure the update happens before it - or use a for, where the header guarantees it.

Common Gotchas

  • Nothing updates the condition. The body must change what the condition reads. If a program hangs, look here first.
  • A semicolon after the header. while (cond); makes the empty statement the body.
  • Testing a variable that was never initialised. The condition runs before the body, so the value it reads has to exist already.
  • char instead of int for getchar. EOF does not fit in a char; the comparison can then never be true, or a legitimate byte can be mistaken for EOF.
  • while (!feof(f)). Loops one time too many. Test the read.
  • Assuming the body runs at least once. It does not. When you need one guaranteed pass - printing a menu before checking the choice - that is a do-while loop.

Frequently Asked Questions

How do you write a while loop in C?

while (condition) { body }. The condition is tested before every pass, so the body runs only while the condition is nonzero, and not at all if it starts false. Something inside the body must eventually change the condition, or the loop never ends.

What is the difference between for and while in C?

They are equally powerful - any for can be rewritten as a while. Use for when a counter, its limit, and its step belong together in one header, and while when the stopping condition is not a count: reading until end-of-file, retrying until success, or looping until a flag flips.

How do I read input until EOF in C?

Test the return value of the input function, not the value it read: while (scanf("%d", &n) == 1) { ... } stops at end-of-file or on the first non-numeric input, and while ((c = getchar()) != EOF) { ... } reads character by character. Never loop on while (!feof(f)) - it runs one extra time past the end.

Why is my while loop infinite in C?

Usually because nothing in the body changes the value the condition tests, or because a stray semicolon after the header (while (i < 10);) made the empty statement the body. Both compile cleanly, so check that the body really updates the condition's variable.

Coddy programming languages illustration

Learn to code with Coddy

GET STARTED