当然fgetc()
回报EOF
when 文件结尾 or an 输入错误 occurs.
这就是全部吗?这是否意味着没有更多数据可用?
FILE *inf = ...;
int ch;
while ((ch = fgetc(inf)) != EOF) {
;
}
if (feof(inf)) puts("End-of-file");
else if (ferror(inf)) puts("Error");
else puts("???");
正在测试feof(), ferror()
充足的?
Note: EOF
这是一个计算结果为负值的宏int
, often -1
。这是not的同义词文件结尾.
我已经发现一些问题 https://stackoverflow.com/questions/tagged/c+fgetc 接近这个问题,但没有列举所有可能性。
这就是全部吗?这是否意味着没有更多可用数据?
不,还有更多方法EOF
.
An EOF
并不一定意味着没有更多数据——这取决于情况。
C 库列出了三种情况fgetc()
回报EOF
.
如果设置了流的文件结束指示符,或者如果流位于文件结束处,则设置流的文件结束指示符,并且fgetc
函数返回EOF
。否则,fgetc
函数返回stream指向的输入流中的下一个字符。如果发生读取错误,则会设置流的错误指示符,并且fgetc
函数返回EOF
。 C17dr § 7.21.7.1 3
回忆每一个stream, like stdin
,有一个文件结束指示符 and 错误指示器.
-
流刚刚遇到文件结尾
(最常见)已尝试获取更多数据,但没有成功。
-
设置流的文件结束指示符
该流首先检查其文件结束指示符。如果发现指示器已设置,则返回EOF
。不会尝试查看是否存在更多数据。某些类型的流将报告EOF
,但数据将在之前到达EOF
报告。直到文件结束指示符被清除为clearerr()
,返回值仍为EOF
. 实施例1 https://stackoverflow.com/a/56755955/2410359. 实施例2 https://stackoverflow.com/a/57272367/2410359.
-
输入错误
溪流error指标是not检查了。然而,由于某种原因,该函数无法读取文件结尾以外的数据。一个常见的例子是fputc(stdin)
。输入错误通常是持续存在的。有些则不然。可能会有更多数据可用。常见的策略是结束输入。
// Example where ferror() is true, yet fgetc() does not return EOF
FILE *inf = stdin;
printf("end-of-file:%d error:%d\n", feof(inf), ferror(inf));
printf("fputc():%d\n", fputc('?', inf)); // EOF reported
printf("end-of-file:%d error:%d\n", feof(inf), ferror(inf));
printf("fgetc():%d\n", fgetc(inf)); // User typed in `A`, 'A' reported
printf("end-of-file:%d error:%d\n", feof(inf), ferror(inf));
Output
end-of-file:0 error:0
fputc():-1
end-of-file:0 error:1
fgetc():65
end-of-file:0 error:1
When ferror()
是真的,这并不意味着错误刚刚发生,只是在过去的某个时间发生。
其他案例
-
明显EOF
由于不正确地另存为char
fgetc()
返回一个int
的值在unsigned char
范围和EOF
- 负值。
When fgetc()
读取字符代码 255,但将其另存为char
在一个系统上char
is signed,这通常会导致char
具有相同的值EOF
,但文件结尾并未发生。
FILE *f = fopen("t", "w");
fputc(EOF & 255, f);
fclose(f);
f = fopen("t", "r");
char ch = fgetc(f); // Should be int ch
printf ("%d %d\n", ch == EOF, ch);
printf("end-of-file:%d error:%d\n", feof(f), ferror(f));
fclose(f);
Output
1 -1 // ch == EOF !
end-of-file:0 error:0
-
系统所在UCHAR_MAX == UINT_MAX
. Rare.
(我只在一些较旧的图形处理器中遇到过这种情况,但 C 仍然允许这样做。)在这种情况下,fgetc()
可能会读到unsigned char
之外的int
范围,因此将其转换为EOF
在函数返回时。因此fgetc()
返回一个恰好等于的字符代码EOF
。这在 C 语言历史上是一个奇怪的现象。主要处理的方法是:
while ((ch = fgetc(inf)) != EOF && !feof(inf) && !ferror(inf)) {
;
}
很少需要这样迂腐的代码。
-
未定义的行为
当然当UB https://en.wikipedia.org/wiki/Undefined_behavior发生,一切皆有可能。
FILE * f = fopen("Some_non_existent_file", "r");
// Should have tested f == NULL here
printf("%d\n", fgetc(f) == EOF); // Result may be 1
处理退货的稳健方法fgetc()
.
FILE *inf = ...;
if (inf) { // Add test
int ch; // USE int !
// Pedantic considerations, usually can be ignored
#if UCHAR_MAX > INT_MAX
clearerr(inf); // Clear history of prior flags
while ((ch = fgetc(inf)) != EOF && !feof(inf) && !ferror(inf)) {
;
}
#else
while ((ch = fgetc(inf)) != EOF) {
;
}
#endif
if (feof(inf)) puts("End-of-file");
else puts("Error");
如果代码需要在之后查找数据文件结尾 or error, call clearerr()
并重复if()
block.
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)