When you're thinking about EOF indications generated from an interactive keyboard, there are two completely different ways of thinking about it. It is easy to accidentally confuse the two.
(1) Most of the time, the operating system is performing a certain amount of "preprocessing" on keyboard input typed by the user, well before an application program — like an ordinary C program — gets ahold of it. For example: if you type a line of input terminated by the Return key, but halfway through the line you make a mistake, and hit the backspace key, and correct it, the application program won't see the mistake, or the backspace key — it will see only the characters in the corrected line.
Similarly, at least on Unix/Linux systems, the vast majority of the time, if the user presses control-D (which is indeed End Of Transmission or EOT or 0x04
in ASCII), the operating system will translate that into an end-of-file indication, and a C program will read EOF, or -1.
(2) If the program is doing something special, and wants to see every keystroke, it may place the operating system's terminal driver into "raw" or "cbreak" mode, meaning that the driver will do minimal or no processing. In that case, if the user presses control-D, the program will indeed read a value of 4, not EOF.
But, as a general rule, code like
while((c = getchar()) != 0x4) { ... }
is incorrect and will not work. On Unix, most of the time, getchar
will never return 4, because control-D will have been translated into an end-of-file indication before the program ever sees it, so the program will see EOF
instead.