繁体   English   中英

fgets(stdin) 旁边的 feof(stdin) 何时返回 true?

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM