我有以下代码:
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。
答案 0 :(得分:6)
问题是fgetc()
及其亲属返回的是int
,而不是char
:
如果未设置stream指向的输入流的文件结束指示符,则为a 如果存在下一个字符,
fgetc
函数会将该字符作为unsigned char
转换为int
,并提升相关文件位置指示符 流(如果已定义)。如果设置了流的文件结束指示符,或者流是在文件末尾,则结束 - 设置了流的文件指示符,
fgetc
函数返回EOF
。
必须返回每个可能的有效字符值和不同的值EOF
(这是负数,通常但不一定是-1
)。
当您将值读入char
而不是int
时,会发生以下两种不良事件之一:
如果普通char
是无符号的,那么你永远不会得到一个等于EOF的值,所以循环永远不会终止。
如果普通char
已签名,那么您可以将合法字符错误地称为0xFF(通常为ÿ,y-umlaut,U + 00FF,带有DIAERESIS的LATIN SMALL LETTER)与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函数中,它比任何其他函数更容易出现故障(不是通过它自己的错误,而是因为用户或程序员使用文件名出错)。
答案 1 :(得分:3)
这是罪魁祸首:
char c;
请将其更改为:
int c;
fgetc
的返回类型为int
,而不是char
。在某些平台中将int
转换为char
时会出现奇怪的行为。