为什么 EOF 在 fgets 和 read 中的行为不同

Why does EOF behave differently in fgets and read

#include <stdio.h>

#define MAXLINE 4096

int 
main(int argc, char **argv)
{
    char           *s;
    char            buf[MAXLINE];

    s = fgets(buf, MAXLINE, stdin);    // here, if replaced with read(0, buf, MAXLINE);        

    return 0;
}

输入为:12ctrl+d

  1. fgets直到再次输入ctrl+d(即:12ctrl+dctrl+d)才会return。为什么 fgets return 遇到第一个 EOF 时? 似乎 12ctrl+d 不起作用。

  2. 但是当s = fgets(buf, MAXLINE, stdin);read(0, buf, MAXLINE);替换时read会return(输入也是:12ctrl+d).

Hitting CTRL+d on the terminal:

  • simply means flush all the characters in stdin (the input buffer) immediately
  • it does NOT trigger an EOF condition on stdin
    (unless the current line/buffer is co-incidentally empty.)

所以在 运行 一个程序,

时按 CTRL+D
  • 一个阻塞的 fgetc() 将 return 如果你连续做两次。
    1st = 刷新当前缓冲的字符,
    2nd = 刷新空缓冲区;即 EOF 条件对 fgetc() 有效并且它 returns
    .
  • 阻塞的 fgetc() 将 return 如果你在空行上执行一次。
    刷新已经空的 stdin 缓冲区,即 EOF 条件对 fgetc() 有效并且它 returns.
  • 一旦输入被刷新,read()return就会立即被阻塞。

查看此 question 的答案了解更多详情。

在常见的实现中,fgets 基于围绕 read 的循环。如果您调用 fgets,它会在内部调用 read。输入 12Ctrl+D 使 read return 这两个字符“12”到 fgets。这还没有形成完整的一行,因此 fgets 再次调用 read。由于我们正在从终端设备而不是文件中读取数据,因此 read 等待您输入更多数据。如果再次键入 Ctrl+Dread returns 0 个字符,fgets 解释为文件结尾,return s.