首页 > 解决方案 > 如何在 C 中使用 fscanf() 区分文件结尾和错误?

问题描述

根据手册,int fscanf(FILE *stream, const char *format, ...)返回成功匹配和分配的输入项的数量,可以少于提供的数量,如果早期匹配失败,甚至为零。我该如何区分:

标签: cscanfeoffeof

解决方案


例如,请参阅 POSIX 规范的“返回值”部分fscanf()

  • 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作为输入(最终的空文件)运行,它什么也不会说。但是,如果您向它提供一个带有单个空白(并且没有换行符)、或者只是一个换行符,或者实际上是任何空白序列的文件,它也不会说什么。您还可以尝试将格式字符串替换为" x %255s". 只给它一个文件x(周围可能有空格)不会产生任何输出。给它一个以 ay作为第一个字符(空格除外)的文件,程序运行很长时间,报告0:每行输出。

请注意,这while (!feof(file))总是错误的,但是在诸如scanf()返回 EOF 之类的函数之后,您可以合法地使用feof()andferror()来区分真正的 EOF 和文件流上的错误(例如磁盘崩溃或……)。

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

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


推荐阅读