最近做东西需要知道文件(txt,html...)究竟是什么编码方式,不然读取文件内容可能出现乱码:
经过网上查找发现两种总结一下,方便自己也方便别人:
①通过判断文件头,不过文件头不是必须的,所以有些文件是没有文件头的
/*
EF BB BF UTF-8
FE FF UTF-16/UCS-2, little endian
FF FE UTF-16/UCS-2, big endian
FF FE 00 00 UTF-32/UCS-4, little endian.
00 00 FE FF UTF-32/UCS-4, big-endian.
*/
参考代码:
BYTE hdBuf[3];
file.Read(hdBuf, 3); //读取文件头来判断是哪种类型
file.SeekToBegin();
if(hdBuf[0] == strtoul(_T("ff"), NULL, 16) && hdBuf[1] == strtoul(_T("fe"), NULL,16))
{
//unicode
}
else if (hdBuf[0] == strtoul(_T("fe"), NULL, 16) && hdBuf[1] == strtoul(_T("ff"), NULL, 16))
{
//unicode big endian
}
else if(hdBuf[0] == strtoul(_T("ef"), NULL,16) &&
hdBuf[1] == strtoul(_T("bb"), NULL, 16)&&
hdBuf[2] == strtoul(_T("bf"), NULL, 16)) //utf8
{
//utf8
}
else
{
//ansi
}
②判断文本是否是utf8,在网上看到的,测试未发现问题,有待进一步验证
参考代码:
inline bool IsTextUTF8(char* str,ULONGLONG length)
{
DWORD nBytes = 0; //UFT8可用1-6个字节编码,ASCII用一个字节
UCHAR chr;
BOOL bAllAscii = true; //如果全部都是ASCII, 说明不是UTF-8
for(int i = 0;i < length;i++)
{
chr = *(str+i);
if( (chr&0x80) != 0 ) // 判断是否ASCII编码,如果不是,说明有可能是UTF-8,ASCII用7位编码,但用一个字节存,最高位标记为0,o0xxxxxxx
bAllAscii = false;
if(nBytes == 0) //如果不是ASCII码,应该是多字节符,计算字节数
{
if(chr >= 0x80)
{
if(chr >= 0xFC && chr <= 0xFD)
nBytes = 6;
else if(chr >= 0xF8)
nBytes = 5;
else if(chr >= 0xF0)
nBytes = 4;
else if(chr >= 0xE0)
nBytes = 3;
else if(chr >= 0xC0)
nBytes = 2;
else
{
return false;
}
nBytes--;
}
}
else //多字节符的非首字节,应为10xxxxxx
{
if( (chr&0xC0) != 0x80 )
{
return false;
}
nBytes--;
}
}
if( nBytes > 0 ) //违返规则
{
return false;
}
if( bAllAscii ) //如果全部都是ASCII, 说明不是UTF-8
{
return false;
}
return true;
}
③windows自带的IsTextUnicode函数,是不靠谱的,如果只是估计那当然没问题了。