I'm in front of something I can't explain. There is no better way of explaining than giving an example :
#include <stdio.h>
int main ()
{
char c;
while (1) {
c = getchar();
printf("%x\n", c);
}
return(0);
}
If I execute this command, it just iterates indefinitely this way:
$ echo -n "A" | ./binary
41
ffffffff
ffffffff
ffffffff
ffffffff
...
From what I know and what I read (Confusion about how a getchar() loop works internally), I thought echo -n "A"
would send a A
to stdin and then trigger an EOF event (I'm not sure what EOF really is) once, thus my loop would iterate twice at most, and then would sleep waiting for a new input in stdin.
But no, it iterates over EOF, and I don't understand why.
I ran this command to try to understand :
$ echo -n "A" | strace ./binary
read(0, "A", 4096) = 1
fstat(1, {st_mode=S_IFCHR|0620, st_rdev=makedev(136, 4), ...}) = 0
mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7ffff7ff6000
write(1, "41\n", 341
) = 3
read(0, "", 4096) = 0
write(1, "ffffffff\n", 9ffffffff
) = 9
read(0, "", 4096) = 0
write(1, "ffffffff\n", 9ffffffff
) = 9
...
So it appears read() is reading nothing, and returns 0, which is interpreted by getchar() as EOF. But why, oh why does it iterate like this, whereas when I execute this binary the normal way, it works as expected :
$ ./binary
A
41
a
B
42
a
^C
$
(Above output could be a bit confusing, but when I entered A then Return, I sent A
then \n
(0x0a) to stdin, so the binary just displays these in their hexa representations ,41
and a
)
Could someone explain this to me ? What did I miss ?
Thanks a lot for reading !
Once you encounter EOF
, getchar
will return immediately with return value EOF
. The stream pointer for the stream will not advance, it will stay on the EOF marker. Subsequent calls to getchar
will also return immediately, since the stream is still at the EOF
marker.
Note that this differs from the behaviour when stdin
is attached to an input device. In that case, getchar
will pause, waiting for further input if the input buffer is empty. getchar
will not return EOF
until an EOF
is sent from the input device (CTRL-D
sends EOF
from a keyboard in Linux).
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