0

So currently I'm learning C from the C programming language 2nd edition book and it says that:

while (c = getchar() != EOF) { } 

is identical to:

while (c != EOF) { c = getchar(); } 

However, when I run the code I just had written:

#include <stdio.h> int main() { char c; int times; while (c = getchar() != EOF) { if (c == 'a') { ++times; } } printf("%d\n", times); } 

The value of times it outputs is 0 instead of actual value of times I typed in 'a' character. Now in this code, it works fine:

#include <stdio.h> int main() { char c; int times; while (c != EOF) { c = getchar(); if (c == 'a') { ++times; } } printf("%d\n",times); } 

and if I type a 3 times, the value it outputs is 3.

4
  • 2
    Was the book expecting c to be of type char? Remember, getchar returns an int. Commented May 12, 2021 at 10:35
  • times is uninitialized, incrementing it is undefined behaviour. Commented May 12, 2021 at 10:40
  • c is also uninitialized in the second version on the first time the while condition is checked. Commented May 12, 2021 at 10:41
  • 1
    Where does The C Programming Lanuage second edition say this? On page 51, it mentions assignment expressions can be used in expressions and uses (c = getchar()) != EOF as an example, and on page 153 it shows that while loop with correct parentheses, but I do not see where it shows that while loop with parentheses missing as it is shown in the question. What page did you copy this from? If the parentheses were in the book and you removed them, then you should remember that computers are mechanical and being precise matters. Source code from books should be reproduced exactly. Commented May 12, 2021 at 11:12

2 Answers 2

5

Precedence!

c = getchar() != EOF 

means

c = ( getchar() != EOF ) // Assigns `0` or `1` to `c`. 

but you want

( c = getchar() ) != EOF 

Also note that c needs to be an int.


This means you could use

for (int c; ( c = getchar() ) != EOF; ) { ... } 

but I prefer

while (1) { int c = getchar(); if (c == EOF) break; ... } 
Sign up to request clarification or add additional context in comments.

2 Comments

You should insist on the other mistake: char c; must be int c; for proper EOF testing.
@chqrlie I didn't go into much detail, but I did mention it
1

Operator precedence. != operator is higher in precedence than =, so your expression is equivalent to:

 while (c = (getchar() != EOF)) 

use a parenthesis around c=getchar() and it will work.

Comments