如何正确确定文本文件的字符编码
How to correctly determine character encoding of text files?
以下是我的情况:我需要正确地确定给定文本文件使用哪个字符编码。希望它能正确地返回以下类型之一:
enum CHARACTER_ENCODING
{
ANSI,
Unicode,
Unicode_big_endian,
UTF8_with_BOM,
UTF8_without_BOM
};
到目前为止,我可以通过调用以下函数正确地判断文本文件是Unicode
、Unicode big endian
或UTF-8 with BOM
。它还可以正确地为ANSI
确定给定的文本文件最初是否不是UTF-8 without BOM
问题是当文本文件是UTF-8 without BOM
时,以下函数会错误地将其视为ANSI
文件
CHARACTER_ENCODING get_text_file_encoding(const char *filename)
{
CHARACTER_ENCODING encoding;
unsigned char uniTxt[] = {0xFF, 0xFE};// Unicode file header
unsigned char endianTxt[] = {0xFE, 0xFF};// Unicode big endian file header
unsigned char utf8Txt[] = {0xEF, 0xBB};// UTF_8 file header
DWORD dwBytesRead = 0;
HANDLE hFile = CreateFile(filename, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
if (hFile == INVALID_HANDLE_VALUE)
{
hFile = NULL;
CloseHandle(hFile);
throw runtime_error("cannot open file");
}
BYTE *lpHeader = new BYTE[2];
ReadFile(hFile, lpHeader, 2, &dwBytesRead, NULL);
CloseHandle(hFile);
if (lpHeader[0] == uniTxt[0] && lpHeader[1] == uniTxt[1])// Unicode file
encoding = CHARACTER_ENCODING::Unicode;
else if (lpHeader[0] == endianTxt[0] && lpHeader[1] == endianTxt[1])// Unicode big endian file
encoding = CHARACTER_ENCODING::Unicode_big_endian;
else if (lpHeader[0] == utf8Txt[0] && lpHeader[1] == utf8Txt[1])// UTF-8 file
encoding = CHARACTER_ENCODING::UTF8_with_BOM;
else
encoding = CHARACTER_ENCODING::ANSI; //Ascii
delete []lpHeader;
return encoding;
}
这个问题困扰了我很长时间,我仍然找不到一个好的解决方案。任何提示都将不胜感激。
对于初学者来说,没有"Unicode"这样的物理编码。你的意思可能是UTF-16。其次,任何文件在"ANSI"或任何单字节编码中都是有效的。你唯一能做的就是按最佳顺序猜测,这最有可能抛出无效匹配。
您应该按照以下顺序进行检查:
- 一开始有UTF-16 BOM吗?那么它可能是UTF-16。使用BOM表作为指示它是大端序还是小端序,然后检查文件的其余部分是否符合
- 一开始有UTF-8 BOM吗?那么它可能是UTF-8。检查文件的其余部分
- 如果以上操作没有得到正匹配,请检查整个文件是否为有效的UTF-8。如果是的话,可能是UTF-8
- 如果上面的结果不是正匹配,那可能是ANSI
如果您希望UTF-16文件也没有BOM(例如,可能是在XML声明中指定编码的XML文件),那么您也必须将该规则推到那里。尽管以上任何一种都可能产生误报,将ANSI文件错误地标识为UTF-*(尽管这不太可能)。您应该始终拥有元数据,该元数据告诉您文件的编码内容,无法100%准确地在事后检测到它。
相关文章:
- 是否有任何区域设置会影响宽字符编码?
- 字符编码和带有C++的文件名
- C 14:UTF-8/UTF-16与本机字符编码之间的转换
- 如何获取 json 文件的字符编码类型
- 字符编码的自动分配
- 如何正确确定文本文件的字符编码
- 是什么决定了C++中的字符编码
- HttpFile::SendRequest和字符编码
- 从 Linux 到 Windows 交叉编译时,我应该如何处理字符编码
- 如何检查在运行程序的控制台上设置了哪些字符编码
- 在c++中转换字符编码
- 标准::字符串字符编码
- Boost:如何检查文本文件字符编码/字符集
- 流级别的字符编码
- 文件字符编码
- 字符编码独立字符交换
- cURL post字段是用特殊字符编码的
- c++是否支持除UTF-8、UTF-16和UTF-32以外的字符编码之间的转换?
- 字符编码-当读取超过127个ASCII值时,C++cin失败
- gettext字符编码