fgetc返回一个未知字符
我有以下代码:
FILE *f = fopen('/path/to/some/file', 'rb'); char c; while((c = fgetc(f)) != EOF) { printf("next char: '%c', '%d'", c, c); }
出于某种原因,当打印出字符时,在文件的末尾,将打印出一个不可渲染的字符以及ASCII序号-1。
next char: '?', '-1'
应该是什么角色? 我知道这不是EOF,因为有一个检查,并且在字符打印后很快,程序SEGFAULT。
问题是fgetc()
及其亲属返回一个int
,而不是一个char
:
如果未设置stream指向的输入流的文件结束指示符并且存在下一个字符,则
fgetc
函数将该字符作为转换为int
的unsigned char
获取,并为该流提前关联的文件位置指示符(如果定义)。如果设置了流的文件结束指示符,或者流位于文件结尾,则设置流的文件结束指示符,并且
fgetc
函数返回EOF
。
它必须返回每个可能的有效字符值和一个不同的值EOF
(它是负数,通常但不一定是-1
)。
当您将值读入char
而不是int
,会发生以下两种不良事件之一:
-
如果plain
char
是无符号的,那么你永远不会得到一个等于EOF的值,所以循环永远不会终止。 -
如果普通
char
被签名,那么你可以将一个合法的字符错误,0xFF(通常是ÿ,y-umlaut,U + 00FF,带有DIAERESIS的LATIN SMALL LETTER Y)视为与EOF相同,因此你过早地检测到EOF。
无论哪种方式,它都不好。
修复
修复是使用int c;
而不是 。 char c;
顺便说一句, fopen()
调用不应该编译:
FILE *f = fopen('/path/to/some/file', 'rb');
应该:
FILE *f = fopen("/path/to/some/file", "rb");
总是检查fopen()
的结果; 在所有I / O函数中,它比任何其他函数更容易出现故障(不是通过它自己的错误,而是因为用户或程序员使用文件名出错)。
这是罪魁祸首:
char c;
请将其更改为:
int c;
fgetc
的返回类型是int
,而不是char
。 在某些平台中将int
转换为char
时会出现奇怪的行为。