I never saw such a while statement before.
while(printf(\"> \"), fgets(str, 100, stdin), !feof(stdin)) {
..
..
}
I read
The two loops given don't have the same meaning. By using the comma operator in that way, the author was able to specify code that should be executed every iteration, even if the loop itself is never entered. It's more like a do ... while ()
loop, or something like the following:
printf("> ");
fgets(str, 100, stdin);
while(!feof(stdin)) {
..
..
printf("> ");
fgets(str, 100, stdin);
}
Your second example has different behavior than the first, and has a bug.
If the line of code:
fgets(str, 100, stdin);
fails because it was a read at the end of the file, then the remainder of the block will be executed.
In the first set of code, the feof()
test occurs after the fgets()
that causes the EOF condition, so the while()
block will not be executed.
Since fgets()
returns NULL if it has hit EOF (and hasn't read any data into the buffer), I might code the loop as:
while (fgets(str, 100, stdin)) {
printf("> ");
// ...
}
which is still slightly different behavior (there will be one fewer "> " printed). If that were important, I'd put an extra instance of that printf()
before the loop.
In general, since it tends to cause confusion, I'd avoid the comma operator except where it's really, really needed or where it won't cause confusion. For example, it's sometimes used in for
loop clauses in a non-confusing manner to allow several variables to be updated on each loop iteration.
while(printf("> "), fgets(str, 100, stdin), !feof(stdin)) {
..
..
}
Commas inside a while behaves more like this:
int feof_wrapper(FILE * stream)
{
printf("> ");
fgets(str, 100, stream);
return feof(stream);
}
while(!feof_wrapper(stdin)) {
..
..
}
Your proposed modification is not equivalent. This is:
while (1) {
printf("> ");
fgets(str, 100, stdin);
if (feof(stdin)) { break; }
...
...
}
I would suggest instead breaking off the work into a function:
int get_input(char* buffer, int size) {
printf("> ");
fgets(buffer, size, stdin);
return !feof(stdin);
}
while (get_input(str, 100)) {
...
...
}
The comma operator is best thought of as, well, an operator. Just like +
is an operator, so that 2 + 3
is an expression (which happens to result in a value of 5
), so too ,
is an operator, and thus 0, 1
is a valid expression (which happens to result in a value of 1
, since that was the last operand).