c - 为什么我在使用 fgets 时必须输入 EOF 3 次?

所以基本上我想将我写入标准输入(包括换行符)的所有内容复制到字符串以用于哈希目的。我设法做到了这一点,并编写了小代码来表示我的问题。

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

#define BUFFERSIZE 10000

int main()
{
char *myStr = calloc(1,1);
char buffer[BUFFERSIZE];

while( fgets(buffer, BUFFERSIZE , stdin) != NULL ){
  myStr = realloc(myStr, strlen(myStr)+1+strlen(buffer) );
  strcat( myStr, buffer );
}
printf("\n%s\n",myStr);

}

当我输入一些文本然后按 ENTER 并在我调用 EOF 后一切正常。

但是当我启动程序时输入“a”然后我尝试调用 EOF(使用 Ctrl Z + (Windows cmd 提示符),Ctrl D (Linux)) 我必须执行 3 次程序才能真正打破循环。我期待最多 2 次。

有人可以解释一下如何使用 EOF、stdin 和 fgets 吗?或者我应该使用其他东西(例如 getline)?很抱歉,如果我不清楚我的问题,请问任何你需要的。

谢谢。

最佳答案

首先,^Z 或 ^D 是控制字符,它们对您正在使用的终端有某种意义,有时这意味着终端发出文件结束条件信号。

无论如何,在输入文本后,终端会处理您的三个按键以执行以下操作:

  1. 刷新输入(即将输入的字符从终端发送到程序——默认情况下不会发生,因为终端使用行缓冲)
  2. 设置文件结束条件
  3. 再次设置文件结束条件

在您的程序中对应于:

  1. 什么都没有发生:即使接收到 afgets 也会继续读取直到文件末尾或换行符
  2. fgets 由于文件结束而完成。但是它不会返回 NULL,因为读取了字符,“a” 是特定的。
  3. A bug in old versions of glibc导致 fgets 尝试再次读取,即使它之前已到达文件末尾。 fgets 由于文件结束而完成,并返回 NULL 因为没有读取字符。

https://stackoverflow.com/questions/29759979/

相关文章:

php - Symfony cron 作业,奇怪的错误

asp.net-mvc - 如何在 web.config 中设置密码和用户名

sql - 使用当前连接从 sql 存储过程调用 dll 函数

python - 列出目录中的所有文件 - 按大小过滤

macos - 将 MAC 上远程桌面中的下移控制向下箭头发送到 Windows PC

ruby - 我在哪里可以看到我的浏览器发送的 http 请求

sql-server - 在任务管理器中误杀了sqlserver.exe进程,如何重启?

sql - 如何在外键约束中使用两列

logging - 日志不打印完整的堆栈跟踪

css - padding-top 不起作用,但 padding-right 是