在 C 中如何使用 fscanf() 区分文件结尾和错误?

How do you differentiate between the end of file and an error using fscanf() in C?

根据手册,int fscanf(FILE *stream, const char *format, ...) returns 成功匹配和分配的输入项数,可能比规定的少,如果早期匹配失败,甚至为零。我该如何区分:

例如,请参阅 POSIX 规范中 fscanf() 的 'return values' 部分。

  • fscanf() 返回 0 报告零个匹配和分配的项目。

  • fscanf() 返回 EOF 报告文件结束。

  • 第一次调用 fscanf() 返回 EOF 时报告空文件。

请注意,该处方很难区分空文件(无字节)和没有有用数据的文件。考虑这个测试程序(我称之为eof59.c,编译创建eof59):

#include <stdio.h>

int main(void)
{
    char buffer[256];
    int rc;

    while ((rc = scanf("%255s", buffer)) != EOF)
        printf("%d: %s\n", rc, buffer);
}

如果你 运行 它以 /dev/null 作为输入(最终的空文件),它什么也没说。然而,如果你给它一个只有一个空白(没有换行符)的文件,或者只是一个换行符,或者实际上是任何白色序列space,它也什么都不说。您还可以尝试用 " x %255s" 替换格式字符串。向它提供一个只有 x 的文件(可能周围有白色 space)不会产生任何输出。为它提供一个以 y 作为第一个字符(白色 space 除外)的文件,并且程序 运行s 长时间报告每行输出 0:

注意 while (!feof(file)) is always wrong,但是在 scanf() 等函数返回 EOF 后,您可以合法地使用 feof()ferror() 来区分真正的 EOF 和文件流错误(例如磁盘崩溃或...)。

if (feof(stdin))
    printf("EOF on standard input\n");
if (ferror(stdin))
    printf("Error on standard input\n");

根据显示的代码,您通常应该会看到 'EOF on standard input';在标准输入上生成(甚至模拟)错误可能非常困难。您不应同时看到这两条消息,而应该始终看到其中一条消息。