pix*_*xis 4 c stdin loops pipe getchar
我面对的是一些我无法解释的事情.除了举例外,没有更好的解释方式:
#include <stdio.h>
int main ()
{
char c;
while (1) {
c = getchar();
printf("%x\n", c);
}
return(0);
}
Run Code Online (Sandbox Code Playgroud)
如果我执行此命令,它只是以这种方式无限迭代:
$ echo -n "A" | ./binary
41
ffffffff
ffffffff
ffffffff
ffffffff
...
Run Code Online (Sandbox Code Playgroud)
从我所知道的和我读(混乱有关的getchar()循环内部是如何工作),我以为echo -n "A"会发A到标准输入,然后触发EOF 事件(我不知道什么EOF真的是)一次,因此我的循环最多迭代两次,然后等待stdin中的新输入.
但不,它迭代EOF,我不明白为什么.
我运行此命令试图理解:
$ 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
...
Run Code Online (Sandbox Code Playgroud)
所以看起来read()没有读任何东西,并返回0,由getchar()解释为EOF.但是为什么,为什么它会像这样迭代,而当我以正常方式执行这个二进制时,它按预期工作:
$ ./binary
A
41
a
B
42
a
^C
$
Run Code Online (Sandbox Code Playgroud)
(上面的输出可能会有点混乱,但是当我进入A然后Return,我送A那么\n(0X0A)到标准输入,所以二进制只是在他们的六交涉显示这些,41和a)
有人可以向我解释一下吗?我错过了什么 ?
非常感谢阅读!
一旦遇到EOF,getchar将立即返回返回值EOF.流的流指针不会前进,它将保留在EOF标记上.随后的调用getchar也将立即返回,因为流仍在EOF标记处.
请注意,这与stdin附加到输入设备时的行为不同.在这种情况下,getchar如果输入缓冲区为空,将暂停,等待进一步输入.直到从输入设备发送(从Linux中的键盘发送)getchar才会返回.EOFEOFCTRL-DEOF
getchar()返回一个int,而不是一个char.较大的返回值允许您查找返回值EOF,即-1.这是错误和文件结束的返回值.将c的类型更改为int不会更改printf的行为.
#include <stdio.h>
int main ()
{
int c;
while (1) {
c = getchar();
if ( c == EOF) {
break;
}
printf("%x\n", c);
}
return(0);
}
Run Code Online (Sandbox Code Playgroud)