I am new to C, and I am trying to understand what goes on in fgets()
when pointed to stdin
.
Basically my question is this, forgive me I might not actually understand fgets()
that well:
If I specify a pointer to some file to use in fgets()
, then fgets()
reads from that location onwards up to either \n
, EOF
, or the specified limit-1
So why does it behave differently if I point to stdin
, in the sense, what makes it wait for user input rather than simply finding nothing to read and hence returning NULL
?
Thank you for your time
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 size-1
characters.
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.
If I specify a pointer to some file to use in fgets(), then fgets() reads from that location onwards up to either \n, EOF, or the specified limit-1
It doesn't read from that location, it reads from that file.
So why does it behave differently if I point to stdin, in the sense, what makes it wait for user input rather than simply finding nothing to read and hence returning NULL?
It doesn't behave any differently. The fgets
function only accepts a pointer to a file and it always reads from that file.
I suspect you're confusing fgets
with some other function that does something else. The fgets
function is, and only is, a function to do a blocking read from a file.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With