[英]When does feof(stdin) next to fgets(stdin) return true?
int main(void){
char cmdline[MAXLINE];
while(1){
printf("> ");
fgets(cmdline, MAXLINE, stdin);
if(feof(stdin)){
exit(0);
}
eval(cmdline);
}
}
这是教授给我的myShell程序的主要部分。
但是有一件事我在代码中不明白。
那里说 if(feof(stdin)) exit(0);
标准输入的结尾是什么?
fgets 接受所有字符,直到输入回车键。 一个典型的“文件”(egtxt)的结尾直观上是可以理解的,但是标准输入的结尾是什么意思呢?
在什么实际情况下 feof(stdin) 实际上返回 true?
即使不输入任何内容而输入空格,IF 语句也不会通过。
feof
测试流的文件结束指示器并返回 true(非零),前提是设置了文件结束指示器。
对于常规文件,尝试读取超过文件末尾会设置文件结束指示符。 对于终端,一个典型的行为是当一个程序试图从终端读取但没有得到数据时,文件结束指示符被设置。 在具有默认设置的 Unix 系统中,触发这种“无数据,文件结束行为”的方法是在行首或紧接在前一个 control-D 之后按 control-D。
这样做的原因是因为 control-D 用于表示“立即将待处理数据发送到程序”。 这在这个答案中有进一步的描述。
因此,如果您想结束程序的输入,请按 control-D(如果不在一行的开头,请再按一次)。
对于来自终端的输入,虽然这确实会导致文件结束指示,但实际上并没有结束输入或关闭 stream。程序可以清除文件结束指示符并继续读取。 即使对于常规文件,程序也可以清除文件结束指示器,将文件上下文重置为不同的 position,然后继续读取。
混淆是假设 stdin = terminal。 这不一定是真的。
stdin 是什么取决于你如何运行你的程序。 例如,假设您的可执行文件名为 a.out,如果您这样运行它:
echo "foo" | ./a.out
Stdin 是一个不同进程的 output,在这个例子中,这个进程简单地输出单词“foo”,所以 stdin 将包含“foo”,然后是 EOF。
另一个例子是:
./a.out < file.txt
在这种情况下,stdin 是“file.txt”。 当文件读到最后时,stdin 得到 EOF。
Stdin 也可以是一个特殊的设备,例如:
./a.out < /dev/random
在这种特定情况下,它是无限的。
最后,当您简单地运行您的程序并且 stdin 是终端时——您也可以生成 EOF——只需按 CTRL-D,这会向终端发送一个表示 EOF 的特殊符号。
PS还有其他方法可以执行流程。 这里我只给出了从命令行shell执行的进程的例子。但是进程可以由不同的进程执行,不一定来自shell。在这种情况下,进程的创建者可以决定stdin是什么——终端,pipe,套接字、文件或任何其他 object。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.