文件读写关于字符的错误&解决方案
最近打哈夫曼编码,压位以后需要支持任意数据的字节流文件读写,然后一堆玄学bug调了我一天。。
好在终于可以把bug汇总了:
1.0x1A问题:用字符文件读入时,读到0x1A会提前中断,返回-1(unsigned char为255)。实际上这是Windows系统一个远古bug,因为曾经0x1A就是EOF,然而现在EOF已经变为-1了。
解决方案:使用rb二进制文件读入,可以防止读入函数进行加工转义。
2.判断文件结束问题:EOF为255,然而对于字符0xFF(255),EOF将会和0xFF重复。然而实际上EOF返回的是一个int类型整数-1,即0xFFFFFFFF,而被unsigned char截断以后,就只剩下了0xFF,无法和字符0xFF区分。
解决方案:使用unsigned short类型读入。
3./r字符自动补全:Windows系统下会自动将/n字符补全为/r/n,所以要判断当前读到的这个/r究竟是自动补全的还是本来就是数据里面的。
解决方案:对于本来就是/n转换成/r/n的,直接跳过/r
对于本来就是/r后面接了一个/n的,将会变成/r/r/n,要去掉其中的一个/r
对于本来就是/r的,读入判断确实只有/r以后,复位按照这一次就是/r的情况进行操作(fseek把文件位置指针转移回来一个)
最终实现的win下fgetc二进制文件的函数:
bool fgetc_windows(FILE *in, unsigned char &ret) { unsigned short ch_buf; if((ch_buf = fgetc(in)) == 0xffff) return false; if(ch_buf == 13 && (ch_buf = fgetc(in)) != 10) { fseek(in, -1, 1); ch_buf = 13; } ret = (unsigned char) ch_buf; return true; }