Since you are testing a program copied from another source, I suppose that you don't want to change it, but understanding it.
getchar()
obtains exactly 1 character from the standard input, which is a file named stdin
in the standard header <stdio.h>
.
The standard input, stdin
, is considered a file.
Formally speaking, the end-of-file is a "mark" and not a "character".
However, in general, a specific "character" is used to mark the "end-of-file" of a text file.
In Windows the "end-of-file" mark is the character CTRL-Z (whose ASCII code is 26).
In Linxu the mark is CTRL-D (whose ASCII code is 4).
On the other hand, the standard input commonly has the following behaviour:
- Wait for user enter characters until an Intro/Enter key is pressed.
If the user does not press Enter, then the standard input does not give back the control to the program. This happens even if you enter an "end-of-file" character (say, CTRL-Z).
However, other behaviours are possible.
For example, in Ubuntu console I obtain that CTRL-D is recognized without waiting for the Enter key be pressed.
In any case, you must explicitely type the end-of-file mark in the console of your system.
So, CTRL-Z (perhaps followed by Enter) or CTRL-D have to be pressed for yourself.
ABOUT ENTER and EOF
After Enter is pressed, your program test for EOF
, that is, the "end-of-file" mark in your system.
However, the Enter keyword does not prints "end-of-file" marks, but only "end-of-line" ones, which corresponds to the standard character newline '\n'
.
Thus, if it is desired that the while()
loop terminates after pressing Intro/Enter, the test must be done against '\n'
, and not EOF
.
AN OBSERVATION
It can be observed that getchar()
doesn't retrieve the character CTRL-Z, because the ASCII code for CTRL-Z is 26, but getchar()
retrieves a negative value (in general -1
).
This means that getchar()
recognizes the character ASCII 26 as and end-of-file mark, and then it converts to a value with meaning in C, provided by the macro EOF
, which is not 26.
What I mean is that EOF
is not CTRL-Z, and then one cannot naively send EOF
under the assumption that the ASCII 26 (CTRL-Z) will be sent to a text file.
Summarizing, I think that it is important to delucidate the abstract concept of "end-of-file", the role of EOF
, and the difference between a "mark" and a "character".
(Another example: in Windows the "mark" for "end-of-line" is the couple of characters CTRL-M CTRL-J, which is not only 1 character, but 2).
Quoted from the standard:
The getchar function returns the next character from the input stream pointed to by
stdin. If the stream is at end-of-file, the end-of-file indicator for the stream is set and
getchar returns EOF. If a read error occurs, the error indicator for the stream is set and
getchar returns EOF.