I am a noob teaching myself to program in C using The C Programming Language, Second Edition (by K&R). In Chapter 1 Section 1.5.1 File Copying, the authors touch very briefly on operational precedence when making comparison between values, underscoring the importance of using parenthesis, in this case, to ensure that assignment is made to the variable 'c' before the comparison is evaluated. They make the assertion that:
c = getchar() != EOF
is equivalent to
c = (getchar() != EOF)
Which "has the undesired effect of setting c
to 0 or 1, depending on whether or not the call of getchar encountered end of file"
The authors then pose Excercise 1-6 - Verify that the expression getchar () != EOF
is 0 or 1
Based on the author's previous assertion, this seemed almost trivial so I created this code:
#include <stdio.h>
main()
{
int c;
while (c = (getchar() != EOF))
putchar(c);
}
Unfortunately, when I run the program, it simply outputs whatever characters I type in the command window rather than the expected string of 1 or 0 if EOF is encountered.
While I am a noob, I think I get the logic that the authors are trying to teach and yet I can not demonstrate this simple task. In this case, should not the variable c
take on the value that the comparison expression evaluated to rather than whatever character getchar()
happens to fetch, particularly because of the location of the parenthesis? If c
is indeed taking on the value of the comparison, putchar()
should only output 0 or 1 and yet, as formulated, it outputs what I type in the command window. What am I doing wrong? What do I not understand? Could it be my compiler? I am coding in in Visual Studio 2017 Community edition on Windows 10 on x64 architecture. I have Tiny C Compiler but have not tried executing from command prompt with TCC yet.
When you run the program, the characters that you see doesn't come from your program. It's the console (or terminal)'s echo funcion that shows whatever character you have typed (and you can even erase them before you hit Enter). Your program only outpus characters with ASCII code 0 or 1, both of which are invisible.
If you change putchar(c)
to printf("%d", c)
you'll be able to see a sequence of 1
s. No zero will appear because when c
becomes zero, the loop stops and it won't be printed.
Characters '0'
and '1'
have the ASCII code of 48 and 49, respectively, despite the fact that your terminal may use another encoding. If you want to output a literal number 0, use the character notation. You can also try putchar(48)
but don't use this too much (You'll later find out that it's highly discouraged to use magic numbers in your program).
putchar('0');
^ ^
The assertion that
c = getchar() != EOF;
is equivalent to
c = (getchar() != EOF);
is because of operator precedence. The operator !=
(inequality) has a higher precedence over =
(value assignment), so it gets evaluated prior to assignment.
Finally, it's extremely rare for someone to have written that. The correct intention is to write this:
while ( (c = getchar()) != EOF )