如何使用 fgets() 从 stdin 中读取?

How to read from stdin with fgets()?

提问人:Oliver 提问时间:12/10/2022 更新时间:12/11/2022 访问量:221

问:

我的教授写了一个关于fgets的C代码,feof使用stdin。 但我不明白它是如何工作的。

fgets(list, 100, stdin);

while (!feof(stdin))
{
    printf("feof!");
    
    fgets(list, 100, stdin);
}

当我写一个“你好”时,函数 while 正在工作。 为什么feof(stdin)返回0?

我认为首先读取所有字符串(包括'\0')的stdin缓冲区。 因此我认为虽然不应该工作,因为 feof(stdin) 返回 1 我怎么了?

c stdin fgets feof

评论

3赞 Some programmer dude 12/10/2022
为什么 “while( !feof(file) )” 总是错的?
0赞 Some programmer dude 12/10/2022
当输入文件到达末尾时,feof 返回 “true”(非零)。对于终端输入,当您按下文件结束键盘序列时(在 Linux 或 macOS 上,在 Windows 中的新行上)会发生这种情况。stdinCtrl-DCtrl-Z
0赞 chux - Reinstate Monica 12/10/2022
“fgets read stdin buffer all of string(include '\0')” --> No. 读取一(包括 a 的字符),将其保存到缓冲区,然后附加一个 .现在缓冲区是一个字符串fgets()'\n''\0'
2赞 Nate Eldredge 12/11/2022
为了让@Someprogrammerdude的评论更明确,你教授的代码是错误的。
0赞 David C. Rankin 12/11/2022
始终使用读取函数的返回来控制读取循环...(你的教授的实现非常尴尬,尽管在技术上不是不正确的)

答:

1赞 chux - Reinstate Monica 12/11/2022 #1

提示:始终检查输入函数和大多数其他 I/O 函数的返回值。

fgets(list, 100, stdin);  // Weak code

是的,在循环内调用具有误导性,因为在给定先前的测试条件的情况下,未设置文件结束指示器。printf("feof!");stdinwhile (!feof(stdin))

如何使用 fgets() 从 stdin 中读取?

不要将 feof() 用于此任务进行主要检测

fgets()在以下情况下返回:NULL

  1. 在上一个输入操作中刚刚发生文件结束。

  2. 甚至在此之前,某些输入操作中就已经发生了文件结束。

  3. 刚刚发生输入错误。示例:要读取的文件是某些串行通信上的输出流或奇偶校验错误。

while (!feof(stdin))仅检测 1 和 2。

除非检查 的返回值,否则使用可能会有问题。fgets(list, 100, stdin)list

feof()在 I/O 函数返回需求的可能性很有用。

尺寸到物体,避免幻数


好用法:

char list[100];
while (fgets(list, sizeof list, stdin)) {
  printf("%s", list):
}

if (feof(stdin)) {
  puts("End-of-file");
} else if (ferror(stdin)) {
  puts("Error");
} else {
  puts("Unexpected state");
}

评论

1赞 David C. Rankin 12/11/2022
总是非常翔实和完整。太糟糕了,我们可以把它“弹出”回关于这个主题的教科书中。