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函数将该字符作为转换为intunsigned 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时会出现奇怪的行为。