我不明白为什么我需要按 Ctrl + D 三次才能发送EOF。
此外,如果按Enter键,则只需要一个 Ctrl + D 来发送EOF。
如何进行更改以便仅使用一个 Ctrl + D 然后它可以检测到EOF?
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#define BUF_SIZE 1024
int main(){
char buffer[BUF_SIZE];
size_t msgLength = 1;
char *msg = malloc(sizeof(char) * BUF_SIZE);
msg[0] = '\0';
printf("Message: ");
while (fgets(buffer, BUF_SIZE, stdin)){
char *old = msg;
msgLength += strlen(buffer);
msg = realloc(msg, msgLength);
strcat(msg, buffer);
}
return 0;
}
答案 0 :(得分:3)
你遇到的问题是终端没有EOF - 它们不是文件,所以“文件结尾”没有任何意义。相反,它们有EOT(传输结束 - Ctrl + D ),由于(快乐?)事故,它通常作为EOF注册到stdio。
UNIX上的文件通过返回0大小读取信号EOF,并且stdio将任何大小0读取视为EOF,无论它是否从文件读取。当且仅当输入缓冲区为空时,EOT才会立即返回终端,这将是0读取(在stdio中触发EOF)。
最简单的解决方案是不要担心 - 如果用户想在此处发出EOF信号,请让用户多次点击 Ctrl + D 。它应该只需要两个,除非你有奇怪的时间问题。
如果你真的想,你可以尝试弄清楚EOT是否被击中 - 如果fgets的结果没有填满缓冲区并且没有以换行结束,那么用户点击EOT来传输它,所以你可以测试它并打破循环。如果用户输入足够的数据来填充fgets缓冲区然后点击EOT,则会失败。如果用户“打字”太快以至于程序无法跟上(当程序实际上没有等待输入时EOT没有效果),它也会失败。我说“打字”,因为终端可能是伪终端,在另一端伪装非常快的输入(包括EOT)
答案 1 :(得分:1)
如果你将这一行添加到你的循环的第一行,在fgets之后,并运行程序,也许它会很有启发性:
printf("GOT: [%s]\n", buffer);
前两个 Ctrl + D 需要结束您输入的部分行,然后是第三个 Ctrl + D ,在目前为止的空行上,关闭输入。