我面前无法解释的事情。没有比给出一个例子更好的解释方式了:
#include <stdio.h>
int main ()
{
char c;
while (1) {
c = getchar();
printf("%x\n", c);
}
return(0);
}
如果我执行此命令,它只是以这种方式无限迭代:
$ echo -n "A" | ./binary
41
ffffffff
ffffffff
ffffffff
ffffffff
...
根据我所知道和我读到的内容(Confusion about how a getchar() loop works internally),我认为echo -n "A"
会向{strong> stdin 发送A
,然后触发EOF 事件(我不确定EOF究竟是什么)一次,因此我的循环最多会迭代两次,然后等待中的新输入标准输入
但不,它迭代了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
...
所以看起来read()没有读任何东西,并返回0,由getchar()解释为EOF。但是为什么,为什么它会像这样迭代,而当我以正常方式执行这个二进制文件时,它按预期工作:
$ ./binary
A
41
a
B
42
a
^C
$
(上面的输出可能有点令人困惑,但当我输入 A 然后返回时,我发送了A
然后\n
(0x0a)到stdin,所以二进制文件只是在它们的六进制表示中显示这些,41
和a
)
有人可以向我解释一下吗?我错过了什么?
非常感谢您的阅读!
答案 0 :(得分:5)
遇到EOF
后,getchar
会立即返回返回值EOF
。流的流指针不会前进,它将保留在EOF标记上。对getchar
的后续调用也会立即返回,因为该流仍位于EOF
标记处。
请注意,这与stdin
附加到输入设备时的行为不同。在这种情况下,如果输入缓冲区为空,getchar
将暂停,等待进一步输入。在{1}}从输入设备发送getchar
(EOF
从Linux中的键盘发送EOF
)之前,CTRL-D
将不会返回EOF
。
答案 1 :(得分:5)
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);
}
答案 2 :(得分:2)
首先,EOF是-1,即0xFFFFFFFF。
系统功能&#39; getchar()&#39;返回一个int,而不是一个char。
所以要进行任何比较,&#39; c&#39;必须是一个int,而不是一个char。
现在,要退出while循环,必须与某些条件进行比较,必须为true才能在循环中继续。
建议使用以下代码模型。
#include <stdio.h>
int main ( void ) //<< for main, better to use 'void' rather than empty braces
{
int c; //<< because getchar() returns an int, not a char
// following loop has EOF as exit condition
// note in C, && is lower presidence than = and != so is evaluated last
// note in C, && is evaluated from left to right
// note to help the compiler to catch errors,
// always place the literal on the left of a comparison
while (c = getchar() && EOF != c)
{
printf("%x\n", c);
}
return(0);
} // end function: main