2012-01-14 80 views
4

手册页说:成功的fgets在输入中遇到EOF时会发生什么?

与fgets()返回小号,并在错误或者虽然没有字符被读取时文件的末尾NULL。

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

+2

我不清楚你想了解什么。当您键入Ctrl-D和其他控制组合键时,您是否想要了解'fgets'的行为或终端的典型行为? – 2012-01-14 11:12:57

回答

6

你描述的行为与fgets无关。在第二次按ctrl-D之前,shell不会关闭输入流。

+0

但是如果我先按Ctrl + D而不输入任何字符,则fgets会返回。在这种情况下,我不需要输入两次。 – Bruce 2012-01-14 11:03:02

+2

当前行中没有字符时,ctrl-D的处理方式会有所不同。在这种情况下,第一次被键入时,它会关闭流。请参阅http://en.wikipedia.org/wiki/Bash_%28Unix_shell%29 – 2012-01-14 11:10:07

+0

在解释行为的同时,我想知道如果在输入几个字符后遇到eof,会发生什么情况。有没有一种好的方法来测试这个?更好的是,除了这个行为是否正确和正式记录的手册页之外,还有其他地方吗? – batbrat 2012-01-14 11:14:03

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

这就像从文本文件中读取存储在磁盘上是不碰巧在最后一个有新的字符线。的fgets()C standard的描述指定它做什么,包括在这种情况下:

char *fgets(char * restrict s, int n, FILE * restrict stream);

与fgets函数读取比n所指定的 字符数少至多一个 指向的流到由s指示的数组。在换行符(保留)或文件结束后,不会读取其他字符 。 A 空字符在最后一个字符读入 后立即写入数组中。

fgets()可以给你一个字符串没有新的行如果输入线太长,或者如果有前档案结尾没有新行。

当您从磁盘文件读取时,到达文件末尾时会出现文件结束条件。当您从交互式设备(如键盘)读取数据时,文件结束条件触发的方式不是由C标准规定的。在类Unix系统上,通过在行的开头键入Control-D或在行的中间键入Control-D两次(尽管控制字符可以重新配置)来触发它。

这是否可能取决于实施。

C99 7.19p2说:

文本流是由成 行字符的有序序列,另外,每个行包括零个或多个字符的 终止换行字符。最后一行是否需要 终止换行字符是实现定义的。

类似Unix的系统通常不需要尾随的换行符。

相关问题