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

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

提问人:tomashauser 提问时间:1/1/2020 更新时间:1/2/2020 访问量:473

问:

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

  • 零匹配和分配的项目
  • 文件末尾
  • 一个空文件?
C 扫描 eof feof

评论


答:

5赞 Jonathan Leffler 1/1/2020 #1

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

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

  • 通过返回 EOF 来报告文件末尾。fscanf()

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

请注意,处方使得很难发现空文件(没有字节)和没有有用数据的文件之间的区别。考虑一下这个测试程序(我叫它,编译创建):eof59.ceof59

#include <stdio.h>

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

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

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

请注意,虽然 (!feof(file)) 总是错误的,但是在函数(如返回 EOF)之后,您可以合法地使用并消除真正的 EOF 与文件流上的错误(例如磁盘崩溃或 ...)之间的歧义。scanf()feof()ferror()

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

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

评论

0赞 tomashauser 1/2/2020
好的,所以如果返回 0,它无法分配项目或文件是空的,如果它返回,文件是空的或它在最后,对吧?fscanf()EOF
1赞 Ed Heal 1/2/2020
如果文件为空 - 无法读取任何内容 - 将返回 EOF
0赞 Antti Haapala -- Слава Україні 1/2/2020
您可以在此处添加有关正确用法和此处:Dfeofferror
0赞 Jonathan Leffler 1/2/2020
@tomashauser——基本上,这是正确的。当遇到 EOF 时,您会得到 EOF,除了跳过格式字符串中的空格或其他文字字符外,什么也没做。如果还剩下一些数据,但格式字符串(例如 在我更新的答案中的代码中)与输入不匹配。fscanf()"x %s"
0赞 S.S. Anne 1/18/2020
“跑了一会儿”是轻描淡写的。