I am new to C, and I am trying to understand what goes on in
fgets() reads from the argument stream. If this stream is tied to a device or a pipe, it blocks until input is obtained from the device/pipe or until an end of file is detected.
stdin is usually tied to the terminal. Reading from the terminal reads any pending input and in the case of
fgets() keeps reading until a newline is typed or enough characters are input. There is one extra layer to understand here: the kernel driver for the terminal performs its own buffering by default, causing the input operation to block until a newline is typed even if more characters are typed than
fgets() expects. These extra characters are left pending in the terminal buffer.
The terminal can be configured for raw mode (as opposed to the default cooked mode) with the
stty system call (on Posix systems). Doing this would remove the buffering in the device driver, but buffering would still be performed in the
FILE * stream.
fgets() can only access characters from the stream after this buffering is performed. Streams tied to devices are usually line buffered by default, causing the stream buffering to match the device drive buffering. If you set both the device to raw mode and the stream as unbuffered, characters will be available to
fgets() as they are typed and
fgets() will stop reading when it gets a newline or when it has read
Note also that you can enter an end of file in cooked mode by typing Control-D on unix and OS/X systems and Control-Z Enter on Windows systems.