解决方案 »
- 在vs2008下配置opencv2.0遇到的问题
- 网络中的宽字符串问题,高人给指点一下吧
- 请教:如何把bmp图象的数据写入内存中,然后再读出显示出来
- installshield 如何实现打多语言包及注册机和注册码 的实现
- ATL COM中能够用继承自CWnd的MFC类吗
- 从对话框获取文档指针、从视图获取文档指针是什么意思?
- JoshuaLi来领分(关于CALLBACK问题)
- 请问:用MFC写出的程序相对于用纯SDK写成的程序性能损失大不大?
- 这么晚了还有谁在线上啊
- window 7 下vs2008中相对路径无法使用的问题
- 如何编程处理 rec 格式的音频文件 ?
- 如何将exe资源中的MENU提取出来
CFile file;
file.Open(_T("D:\\d.txt"),CFile::modeRead,NULL); //路径改成你自己的文件路径
wchar_t wcText;
file.Read(&wcText,sizeof(wchar_t)); //读取文件头来判断是哪种类型
if(wcText == 0xFEFF)
{
//UNICODE
}
else if(wcText == 0xFFFE)
{
//UNICODE BIG ENDINA
}
else if(wcText == 0xBBEF)
{
//UTF-8
}
else
{
//ANSI
}
主要是排除法。一直往下读文件,在几种可能的编码中,发现一种编码的非法字符就排除一种,剩下的那种就认为是了,要是读完了文件还有两种以上为被排除那就当使用率高的显示。
1 用记事本打开,菜单-文件-另存为,就可以看到其编码格式了
2 在我的程序里,用 ansi 方式读取ansi 编码文件,正常
用 ansi 方式读取utf-8编码文件,乱码
用 utf-8方式读取ansi 编码文件,程序出错
用 utf-8方式读取utf-8编码文件,正常
baby393 兄,谢谢了,我不只是要判断它是什么编码,还要根据编码不同使用不同的代码读取并显示文件
看看pfx\src\pfxeditctrl.cpp里面的BOOL CPfxEditDoc::FileIsUtf8(LPCSTR pData, LONG cch)
和pfx\inc\pfxeditctrl.h里面的class CPfxEditDoc::class CPfxEditDocUtf8Converter类,它是一个UTF8解码类, 可重复使用。
例如LPSTR pFileData 是你的文本数据的第一个字节
LPSTR pNextUtf8Character = pFileData + Utf8CharSize(pFileData);// 以此类推...
pNextUtf8Character = pNextUtf8Character + Utf8CharSize(pNextUtf8Character);其实当你判断出文本数据是UTF8格式后,你可以用Utf8ToUnicode直接将数据转换成UNICODE再处理。
要计算整快UTF8转换后需要多大的缓冲区可以使用//这时函数返回需要的缓冲区大小
LONG nBufferSizeInUnicode = Utf8ToUnicode(pUtf8Data, nCountOfUtf8DataSizeInBytes, NULL, 0);//申请缓冲区。
LPWSTR pUnicodeBuffer = new WCHAR[nBufferSizeInUnicode];//解码转换(它不一定是以NULL结尾的数据。)
Utf8ToUnicode(pUtf8Data, nCountOfUtf8DataSizeInBytes, pUnicodeBuffer, nBufferSizeInUnicode);
//现在pUnicodeBuffer里面的是UNICODE字符可以使用了。
{
BOOL ret = TRUE;
while (*lpString != '\0')
{
if (*lpString < 0x80)
lpString++;
else if ((*lpString >= 0xC0) && (*lpString < 0xE0))
{
if (((BYTE)(lpString[1] - 0x80)) < 0x40)
lpString += 2;
else
{
ret = FALSE;
break;
}
}
else if ((*lpString >= 0xE0) && (*lpString < 0xF0))
{
if ((((BYTE)(lpString[1] - 0x80)) < 0x40) && (((BYTE)(lpString[2] - 0x80)) < 0x40))
lpString += 3;
else
{
ret = FALSE;
break;
}
}
else if ((*lpString >= 0xF0) && (*lpString < 0xF8))
{
if ((((BYTE)(lpString[1] - 0x80)) < 0x40) && (((BYTE)(lpString[2] - 0x80)) < 0x40) && (((BYTE)(lpString[3] - 0x80)) < 0x40))
lpString += 4;
else
{
ret = FALSE;
break;
}
}
else if ((*lpString >= 0xF8) && (*lpString < 0xFC))
{
if ((((BYTE)(lpString[1] - 0x80)) < 0x40) && (((BYTE)(lpString[2] - 0x80)) < 0x40) && (((BYTE)(lpString[3] - 0x80)) < 0x40) && (((BYTE)(lpString[4] - 0x80)) < 0x40))
lpString += 5;
else
{
ret = FALSE;
break;
}
}
else if ((*lpString >= 0xFC) && (*lpString < 0xFE))
{
if ((((BYTE)(lpString[1] - 0x80)) < 0x40) && (((BYTE)(lpString[2] - 0x80)) < 0x40) && (((BYTE)(lpString[3] - 0x80)) < 0x40) && (((BYTE)(lpString[4] - 0x80)) < 0x40) && (((BYTE)(lpString[5] - 0x80)) < 0x40))
lpString += 6;
else
{
ret = FALSE;
break;
}
}
}
return ret;
}
你这个函数是有重大BUG的。
static const BYTE str[] = {0x41, 0x42, 0x43, 0xE4, 0xB8, 0xAD, 0xE5, 0x00};
IsUTF8(str); // 不崩溃你告诉我!!!
没崩溃我告诉你,而且我不知道你为什么说会崩溃。
((BYTE)(lpString[1] - 0x80)) < 0x40)这个条件在最后0x00的时候是不满足条件的,&&后面lpString[2]根本不会被访问到,直接跳else去break出循环了。
汗!