Alf P. Steinbach said:
... you [need to] generate an end of file [from keyboard input].
In Unix, use Ctrl D to submit zero bytes, which is then
interpreted as end of file; in Windows, use Ctrl Z followed by return,
where the control character itself is interpreted as end of file.
<OT>
I'm not sure what you mean by "submit zero bytes", but I don't believe
that's what it does.
</OT>
This is indeed off topic, but I will take a dollar out of the
metaphorical jar.
On a Unix-like system, keyboard input is routed through an
interpretation layer, often called a "tty driver" for historical
reasons. This interpretation layer has several modes, usually
called "cooked", "cbreak", and "raw". In "raw" mode all input
characters are passed through immediately and unchanged. In
"cbreak" mode, most characters are passed through immediately and
unchanged; a few are interpreted specially. In the most usual,
"cooked" mode, however, characters are collected up for input
editing, allowing the user to erase incorrect input, up to a point.
In cooked mode, there are a number of user-specified special
characters, including one called the "EOF character". This is
normally set to control-D. Internally, however, it is not really
an "EOF character" at all. Instead, it has almost the same
effect as pressing the ENTER or RETURN key.
The key labeled ENTER (or RETURN) usually sends a control-M to
the connected serial port. What? Oh, right, we have another
historical artifact here.
Modern keyboards send key-up/key-down codes over some sort of
connection (often, now, a USB or wireless channel). However, on
a typical Unix-like system, a software layer translates these
into what look like serial-port signals coming from an old-style
terminal device. These old-style terminal devices, common back
in the 1980s, would send control-M when you pushed ENTER.
Anyway, back to the "tty driver" software layer: when it sees a
control-M (in cooked mode), it translates it to a control-J (or
"line feed" or '\n') character. Then it falls through to the code
that handles a control-J. This code puts the control-J into the
edit buffer, and then sends the current contents of the edit buffer
up through the rest of the system's software layers, to be returned
from a read() system call and delivered to -- in this case -- your
program using C's "stdin" stream.
Most other ordinary characters simply go into the edit buffer, and
are (optionally) echoed back to the output serial port -- which,
in many cases today, is another fake, made out of yet another
software layer that connects to a display of some sort, or reroutes
to a window system, or some such; but that is yet another can of
worms. There they sit, waiting to be edited (deleted or added-to
or whatever) until you press ENTER.
If you press the EOF key (normally control-D), however, the tty
driver does almost the same thing that it does for control-J. For
control-J, it adds the '\n' to the edit buffer and sends the
contents back up the layers. For control-D, it skips the "add"
part, and sents the buffer contents up. IF THE BUFFER IS EMPTY,
this causes the read() system call to return 0. If the buffer
is *not* empty, the read() system call returns some positive
number, and C's "stdin" stream collects up a sequence of characters
that does *not* end with a '\n'.
Whenever a read() system call returns 0, a Unix-like system's stdio
interprets that as "end of input", and delivers an EOF from the
stream. So pressing ^D does, in this case, "submit zero bytes",
as long as you press it with an empty cooked-mode edit buffer.