Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/loops/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
当通过管道提供STDIN时,getchar()在EOF上循环_C_Loops_Pipe_Stdin_Getchar - Fatal编程技术网

当通过管道提供STDIN时,getchar()在EOF上循环

当通过管道提供STDIN时,getchar()在EOF上循环,c,loops,pipe,stdin,getchar,C,Loops,Pipe,Stdin,Getchar,我遇到了一些我无法解释的事情。没有比举个例子更好的解释方法了: #include <stdio.h> int main () { char c; while (1) { c = getchar(); printf("%x\n", c); } return(0); } 根据我所知道的和我所读到的(),我认为echo-n“A”会将A发送到stdin,然后触发一个EOF事件(我不确定EOF到底是什么)一次,这样我的循环最多会

我遇到了一些我无法解释的事情。没有比举个例子更好的解释方法了:

#include <stdio.h>

int main ()
{
    char c;
    while (1) {
        c = getchar();
        printf("%x\n", c);
    }
   return(0);
}
根据我所知道的和我所读到的(),我认为
echo-n“A”
会将
A
发送到stdin,然后触发一个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
...
所以看起来read()没有读取任何内容,并返回0,这被getchar()解释为EOF。但是为什么,为什么它会这样迭代,而当我以正常的方式执行这个二进制文件时,它会像预期的那样工作:

$ ./binary
A
41
a
B
42
a
^C
$
(上面的输出可能有点混乱,但当我输入一个then Return时,我将
a
然后
\n
(0x0a)发送到stdin,因此二进制文件只以六边形表示,
41
a

有人能给我解释一下吗?我错过了什么


非常感谢您的阅读

一旦遇到
EOF
getchar
将立即返回值
EOF
。流的流指针不会前进,它将停留在EOF标记上。对
getchar
的后续调用也将立即返回,因为流仍处于
EOF
标记处

请注意,这与将
stdin
连接到输入设备时的行为不同。在这种情况下,
getchar
将暂停,如果输入缓冲区为空,则等待进一步的输入
getchar
在从输入设备发送
EOF
之前不会返回
EOF
CTRL-D
从Linux键盘发送
EOF

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);
}
#包括
int main()
{
INTC;
而(1){
c=getchar();
如果(c==EOF){
打破
}
printf(“%x\n”,c);
}
返回(0);
}

首先,EOF为-1,即0xFFFFFF

系统函数“getchar()”返回一个int,而不是char

因此,要进行任何比较,“c”必须是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
#包括

int main(void)//好的,这很有用!感谢您的回答,已被接受:)
char c
将永远不会与
EOF
进行比较,如果
char
未签名。如果为某些非ASCII字符(将产生相应负值的字符为
EOF
)签名,则它将等于
EOF
。感谢此精度
#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