如果指向标准输入,是什么让 fgets() 实际上等待用户输入?

What makes fgets() actually wait for user input if pointed to stdin?

我是 C 的新手,我想了解 fgets() 指向 stdin 时发生了什么。

基本上我的问题是这样的,请原谅我可能不太理解 fgets():

如果我指定指向某个文件的指针以在 fgets() 中使用,则 fgets() 从该位置向上读取到 \nEOF 或指定 limit-1

那么,如果我指向 stdin,为什么它的行为会有所不同,从某种意义上说,是什么让它 等待 用户输入,而不是简单地找不到任何可读和因此返回 NULL?

感谢您的宝贵时间

If I specify a pointer to some file to use in fgets(), then fgets() reads from that location onwards up to either \n, EOF, or the specified limit-1

它不是从 位置 读取,而是从 文件 读取。

So why does it behave differently if I point to stdin, in the sense, what makes it wait for user input rather than simply finding nothing to read and hence returning NULL?

它的行为没有任何不同。 fgets 函数 接受指向文件的指针,并且它 总是 从该文件读取。

我怀疑您将 fgets 与其他一些执行其他操作的函数混淆了。 fgets 函数是且仅是从文件执行阻塞读取的函数。

fgets() 从参数流中读取。如果此流绑定到设备或管道,它将阻塞直到从 device/pipe 获得输入或直到检测到文件结尾。

stdin 通常绑定到终端。从终端读取会读取任何待处理的输入,在 fgets() 的情况下会一直读取,直到输入换行符或输入足够的字符。这里还有一层需要理解:终端的内核驱动程序默认执行自己的缓冲,导致输入操作阻塞,直到输入换行符,即使输入的字符多于 fgets() 预期也是如此。这些额外的字符留在终端缓冲区中。

可以使用 stty 系统将终端配置为 raw 模式(相对于默认的 cooked 模式)调用(在 Posix 系统上)。这样做会删除设备驱动程序中的缓冲,但仍会在 FILE * 流中执行缓冲。 fgets() 只能在执行此缓冲后访问流中的字符。默认情况下,绑定到设备的流通常是行缓冲的,导致流缓冲与设备驱动器缓冲相匹配。如果您将设备设置为原始模式并将流设置为无缓冲,字符将在输入时可供 fgets() 使用,并且 fgets() 将在收到换行符或已读取时停止读取 size-1个字符。

另请注意,您可以通过在 unix 和 OS/X 系统上键入 Control-D 并在 Windows 系统。