fgetc函数
函数原型:int fgetc(FILE* stream);
参数说明:参数为一个文件指针,表明可以从任何流中读取字符。
返回值说明:读取成功返回该字符,读取失败或者读取到文件末尾(EOF)则返回EOF(-1)。
返回值的类型注意是int类型而不是char类型,如果定义一个char类型的变量会出现以下两种非预期的错误。
当编译器把char类型翻译成usigned char时,while变成死循环。
char ch;
while(ch = getc(fp)) != EOF)
{
}
/*
ch的值一定是0x00-0xff(就算getc函数读到了EOF,但是由于接受的是unsigned char,那么这个-1就会溢出成0xff),一旦和EOF这个int类型比较,那么ch就会提升为int类型
无符号低字节变高字节,高位补0.于是ch的值由0x00000000-0x000000ff。
在有符号数的范畴下,这个范围永远非负,所以该循环永远进行。
char ch;
while(ch = getc(fp)) != EOF)
{
}
/*
ch的值一定是0x00-0xff(就算getc函数读到了EOF,但是由于接受的是unsigned char,那么这个-1就会溢出成0xff),一旦和EOF这个int类型比较,那么ch就会提升为int类型
无符号低字节变高字节,高位补0.于是ch的值由0x00000000-0x000000ff。
在有符号数的范畴下,这个范围永远非负,所以该循环永远进行。
*/
当编译器把char类型翻译成signed char时,存在字符被误当作EOF。
char ch;
while(ch = getc(fp)) != EOF)
{
}
/*
假如读取一个字符为0xff(这是有可能的扩展ascii码字符中有值为255的ascii码),那么ch = 0xff(带符号),那么在和EOF进行比较时,同样被提升为int类型,有符号低字节变高字节,高位补符号位。
提升后的ch = 0xffffffff。这与EOF(宏定义为 -1)的补码形式一样。那么字符ascii码值为0xff的字符就会被解释成EOF文件结束符,事实上它并不是EOF。
char ch;
while(ch = getc(fp)) != EOF)
{
}
/*
假如读取一个字符为0xff(这是有可能的扩展ascii码字符中有值为255的ascii码),那么ch = 0xff(带符号),那么在和EOF进行比较时,同样被提升为int类型,有符号低字节变高字节,高位补符号位。
提升后的ch = 0xffffffff。这与EOF(宏定义为 -1)的补码形式一样。那么字符ascii码值为0xff的字符就会被解释成EOF文件结束符,事实上它并不是EOF。
*/
如果我们正常的使用int类型来接收返回值。
int 一般编译器都解释为signed int类型。首先不需要存在什么提升的问题,一开始就被解释为32位。正常的字符的范围此时应该是0x0000000-0x000000ff。而EOF此时是0xffffffff,这就很好的和所有正常字符进行了区分,避免了上面两种情况。
温馨提示:在理解时注意用int类型接收这种情况中的正常字符的范围是除去EOF的,但是char第一种情况是,那个是就算是EOF也被处理成了正常字符中的一部分(溢出之后)。并且还永远非负。
【注】 如果不了解整型间转换机制的同学可以去阅读这篇博客。下附链接
数据转换(整型转换)。
————————————————
版权声明:本文为CSDN博主「Xuefu_836782243」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/Xuefu_836782243/article/details/104399689
本文详细解析了fgetc函数中字符类型转换导致的错误,包括unsigned char溢出和signed char误判EOF。重点讲解了使用int类型接收返回值的重要性,并提供了相关整型转换机制的背景知识。

169

被折叠的 条评论
为什么被折叠?



