当通过管道提供 STDIN 时,getchar() 在 EOF 上循环
getchar() loops over EOF when STDIN provided through a pipe
我面对无法解释的事情。没有比举个例子更好的解释方法了:
#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"
会发送一个 A
到 stdin 然后触发一个 EOF event(我不确定 EOF 到底是什么)once,因此我的循环最多会迭代两次,然后会休眠等待 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
...
所以看起来 read() 没有读取任何内容,returns 0 被 getchar() 解释为 EOF。但是为什么,为什么它会像这样迭代,而当我以正常方式执行这个二进制文件时,它会按预期工作:
$ ./binary
A
41
a
B
42
a
^C
$
(上面的输出可能有点混乱,但是当我输入 A 然后 Return 时,我发送了 A
然后 \n
(0x0a) 到 stdin,所以二进制只显示它们的十六进制表示,41
和 a
)
有人可以给我解释一下吗?我错过了什么?
非常感谢阅读!
一旦遇到EOF
,getchar
会立即return,return值EOF
。流的流指针不会前进,它会停留在 EOF 标记上。对 getchar
的后续调用也将立即 return,因为流仍在 EOF
标记处。
请注意,这与 stdin
附加到输入设备时的行为不同。在这种情况下,getchar
将暂停,如果输入缓冲区为空,则等待进一步的输入。 getchar
不会 return EOF
直到 EOF
从输入设备发送(CTRL-D
从 [=26= 中的键盘发送 EOF
]).
getchar() return是一个 int,不是 char。较大的 return 值允许您查找 return 值 EOF,即 -1。这是错误和文件结尾的 return 值。将 c 的类型更改为 int 不会更改 printf 的行为。
#include <stdio.h>
int main ()
{
int c;
while (1) {
c = getchar();
if ( c == EOF) {
break;
}
printf("%x\n", c);
}
return(0);
}
首先,EOF 为 -1,即 0xFFFFFFFF。
系统函数 'getchar()' returns 一个 int,而不是一个 char。
所以要进行比较,'c' 必须是 int,而不是 char。
现在,要退出 while 循环,必须与某些条件进行比较,该条件必须为真才能继续循环。
建议使用以下代码模型。
#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
我面对无法解释的事情。没有比举个例子更好的解释方法了:
#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"
会发送一个 A
到 stdin 然后触发一个 EOF event(我不确定 EOF 到底是什么)once,因此我的循环最多会迭代两次,然后会休眠等待 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
...
所以看起来 read() 没有读取任何内容,returns 0 被 getchar() 解释为 EOF。但是为什么,为什么它会像这样迭代,而当我以正常方式执行这个二进制文件时,它会按预期工作:
$ ./binary
A
41
a
B
42
a
^C
$
(上面的输出可能有点混乱,但是当我输入 A 然后 Return 时,我发送了 A
然后 \n
(0x0a) 到 stdin,所以二进制只显示它们的十六进制表示,41
和 a
)
有人可以给我解释一下吗?我错过了什么?
非常感谢阅读!
一旦遇到EOF
,getchar
会立即return,return值EOF
。流的流指针不会前进,它会停留在 EOF 标记上。对 getchar
的后续调用也将立即 return,因为流仍在 EOF
标记处。
请注意,这与 stdin
附加到输入设备时的行为不同。在这种情况下,getchar
将暂停,如果输入缓冲区为空,则等待进一步的输入。 getchar
不会 return EOF
直到 EOF
从输入设备发送(CTRL-D
从 [=26= 中的键盘发送 EOF
]).
getchar() return是一个 int,不是 char。较大的 return 值允许您查找 return 值 EOF,即 -1。这是错误和文件结尾的 return 值。将 c 的类型更改为 int 不会更改 printf 的行为。
#include <stdio.h>
int main ()
{
int c;
while (1) {
c = getchar();
if ( c == EOF) {
break;
}
printf("%x\n", c);
}
return(0);
}
首先,EOF 为 -1,即 0xFFFFFFFF。
系统函数 'getchar()' returns 一个 int,而不是一个 char。
所以要进行比较,'c' 必须是 int,而不是 char。
现在,要退出 while 循环,必须与某些条件进行比较,该条件必须为真才能继续循环。
建议使用以下代码模型。
#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