【发布时间】:2020-04-20 13:13:30
【问题描述】:
根据手册,int fscanf(FILE *stream, const char *format, ...)返回成功匹配和分配的输入项的数量,可以少于提供的数量,如果早期匹配失败,甚至为零。我该如何区分:
- 零匹配和分配的项目
- 文件结束
- 一个空文件?
【问题讨论】:
根据手册,int fscanf(FILE *stream, const char *format, ...)返回成功匹配和分配的输入项的数量,可以少于提供的数量,如果早期匹配失败,甚至为零。我该如何区分:
【问题讨论】:
例如,请参阅fscanf() 的 POSIX 规范的“返回值”部分。
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 的文件(可能周围有空格)不会产生任何输出。给它一个以y 作为第一个字符(除了空格)的文件,程序运行很长时间,在每行输出中报告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”;在标准输入上生成(甚至模拟)错误可能会非常困难。您不应同时看到两条消息,而应始终看到其中一条消息。
【讨论】:
fscanf()返回0,则表示分配项目失败或文件为空,如果返回EOF,则文件为空或在末尾,对吧?
feof和ferror的正确使用:D
fscanf() 遇到 EOF 并且除了跳过空格或格式字符串中的其他文字字符之外什么都不做时,您会得到 EOF。如果还有一些数据,但格式字符串(例如我更新的答案中的代码中的"x %s")与输入不匹配,您会得到 0。