fgetc返回一个未知字符

0 c stdio

我有以下代码:

FILE *f = fopen('/path/to/some/file', 'rb');
char c;
while((c = fgetc(f)) != EOF)
{
    printf("next char: '%c', '%d'", c, c);
}
Run Code Online (Sandbox Code Playgroud)

出于某种原因,当打印出字符时,在文件的末尾,打印出一个不可渲染的字符,以及ASCII序号-1.

next char: '?', '-1'
Run Code Online (Sandbox Code Playgroud)

应该是什么角色?我知道这不是EOF,因为有一个检查,并且在打印字符后很快,程序SEGFAULT.

Jon*_*ler 6

麻烦的是,fgetc()它的亲戚回来了int,而不是char:

如果未设置stream指向的输入流的文件结束指示符并且存在下一个字符,则该fgetc函数将该字符作为unsigned char转换为a获得int并推进该流的关联文件位置指示符(如果已定义) .

如果设置了流的文件结束指示符,或者流位于文件结尾,则设置流的文件结束指示符并fgetc返回该函数EOF.

它必须返回每个可能的有效字符值和一个不同的值EOF(这是负面的,通常但不一定-1).

当您将值读入char而不是a时int,会发生以下两种不良事件之一:

  • 如果plain char是无符号的,那么你永远不会得到一个等于EOF的值,所以循环永远不会终止.

  • 如果plain char是签名的,那么你可以把一个合法的字符错误,0xFF(通常是ÿ,y-umlaut,U + 00FF,LATIN SMALL LETTER Y WITH DIAERESIS)和EOF一样对待,所以你过早地检测到了EOF.

无论哪种方式,它都不好.

修复

修复是使用int c;而不是char c;.


顺便说一下,fopen()调用不应该编译:

FILE *f = fopen('/path/to/some/file', 'rb');
Run Code Online (Sandbox Code Playgroud)

应该:

FILE *f = fopen("/path/to/some/file", "rb");
Run Code Online (Sandbox Code Playgroud)

经常检查结果fopen(); 在所有I/O函数中,它比任何其他函数更容易出现故障(不是通过它自己的错误,而是因为用户或程序员使用文件名出错).