我在linux上面临fgets()的一些问题。 fgets从关闭的文件描述符返回数据。 如果文件关闭,我希望它返回EOF。 我能够提出我的问题的简化版本。
int main()
{
int i=0, j;
FILE *FD;
char p[128];
FD = fopen("junk", "r");
while(fgets(p, sizeof(p), FD))
{
close(fileno(FD));
printf("lineno=%d\n", i++);
}
return 0;
}
我希望它只打印一行。 这个问题有解决办法吗?
更新: 正如有人在下面回答的那样,fgets正在缓冲文件 甚至在FD关闭后返回数据。 它正在缓冲4kB的数据。如果文件大小超过4k, 读取4KB后,它会获得EOF,打印停止。否则,如果 文件大小谢谢4k,它打印到文件末尾。
答案 0 :(得分:5)
在已关闭的文件上调用fgets()具有未定义的行为。换句话说,不保证返回EOF。
答案 1 :(得分:1)
像其他人所说,close(fileno(FD));
是一个坏主意。如果这样做,相同的文件描述符可能会被重用于另一个文件,而fgets
会突然读取该fd。对于多线程应用程序尤其如此。
此外,fgets已缓冲。它可能在第一次调用时从文件中读取了大量数据,然后调用只返回缓冲区中的更多数据。
相反,做这样的事情:
int main(void)
{
int i=0, j;
FILE *FD;
char p[128];
FD = fopen("junk", "r");
while(FD && fgets(p, sizeof(p), FD))
{
fclose(FD);
FD = NULL;
printf("lineno=%d\n", i++);
}
return 0;
}
答案 2 :(得分:0)
关闭后使用文件描述符可能会导致不可预测/未定义的行为。你可能应该避免这样做。
发布的示例中可能发生的是打开并读取流。读取数据可能会将更多数据放入基础流中。因此,即使基础文件描述符已关闭,流的句柄仍将包含更多要读取的数据。同样,这可能是不可预测的。