当fgets在输入中间遇到EOF时会发生什么?

时间:2012-01-14 10:50:16

标签: c

手册页说:

  

fgets()在成功时返回s,在出错时或在文件结束时没有读取任何字符时返回NULL。

我写了一个小的C文件,调用fgets来测试它的行为。我特别想看看在输入一些字符后EOF出现时会发生什么。我在bash上使用了eof组合键(Ctrl + D)。我必须按两次Ctrl + D才能返回fgets。它打印出输入的字符,直到我按两次Ctrl + D。输入一些字符后按Ctrl + D一次完全没有效果。如果我在此之后输入了一些字符,则将它们存储在传递的数组中。为什么fgets的表现如此?

3 个答案:

答案 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系统通常不需要尾随的换行符。