手册页说:
fgets()在成功时返回s,在出错时或在文件结束时没有读取任何字符时返回NULL。
我写了一个小的C文件,调用fgets来测试它的行为。我特别想看看在输入一些字符后EOF出现时会发生什么。我在bash上使用了eof组合键(Ctrl + D)。我必须按两次Ctrl + D才能返回fgets。它打印出输入的字符,直到我按两次Ctrl + D。输入一些字符后按Ctrl + D一次完全没有效果。如果我在此之后输入了一些字符,则将它们存储在传递的数组中。为什么fgets的表现如此?
答案 0 :(得分:6)
您描述的行为与fgets无关。在第二次按ctrl-D之前,shell不会关闭输入流。
答案 1 :(得分:4)
你应该发现,如果在读取至少一些字符之后但在遇到换行符之前输入结束fgets
返回非空(指向提供的缓冲区的指针)并且提供的缓冲区将不包含换行符但会被终止。
这就是fgets
的文档所说的内容。
E.g。
#include <stdio.h>
int main(void)
{
char buffer[200];
char* ret = fgets(buffer, sizeof buffer, stdin);
printf("exit code = %p\n", (void*)ret);
if (ret != 0)
{
printf("read code = %s<--END\n", buffer);
}
return 0;
}
输出:
$ printf "no newline here->" | ./a.out
exit code = 0x7fff6ab096c0
read code = no newline here-><--END
或:
$ printf "newline here->\nmore text\n" | ./a.out
exit code = 0x7fff6f59e330
read code = newline here->
<--END
没有输入:
$ printf "" | ./a.out
exit code = (nil)
答案 2 :(得分:2)
就像读取存储在磁盘上的文本文件一样,在最后一行的末尾没有新行字符。 fgets()
对char *fgets(char * restrict s, int n,
的描述指明了它的作用,包括在这种情况下:
如果输入行太长而不适合,或者在文件结束之前没有换行,
FILE * restrict stream);
fgets()
fgets 函数最多读取的数量少于1 由流指向的流中的 n 指定的字符 进入 s 指向的数组。不会读取其他字符 在换行符后(保留)或文件结束后。一个 在最后一个字符读取后立即写入空字符 进入阵列。
{{1}}可以为您提供没有换行符的字符串。
当您从磁盘文件中读取时,到达文件末尾时会出现文件结束条件。当您从诸如键盘的交互式设备进行读取时,C标准未指定触发文件结束条件的方式。在类Unix系统上,通过在行的开头键入 Control-D 或通过在行的中间键入 Control-D 来触发它(尽管控制字符可以重新配置)。
这是否可能取决于实施。
C99 7.19p2说:
文本流是由字符组成的有序字符序列 行,每行由零个或多个字符加上a组成 终止换行符。最后一行是否需要 终止换行符是实现定义的。
类Unix系统通常不需要尾随的换行符。