我的情况是这样的:我需要正确地确定一个文本文件使用的字符编码。希望它能正确地返回以下一种类型:
enum CHARACTER_ENCODING
{
ANSI,
Unicode,
Unicode_big_endian,
UTF8_with_BOM,
UTF8_without_BOM
};
到目前为止,我可以通过调用以下函数正确地识别文本文件是 Unicode
,Unicode big endian
还是带有 BOM 的 UTF-8
。它也可以正确地确定对于 ANSI
,如果给定的文本文件不是原始的不带 BOM 的 UTF-8
。问题在于,当文本文件是不带 BOM 的 UTF-8
时,以下函数会错误地将其视为一个 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;
}
这个问题已经困扰我很长一段时间了,但我还是找不到一个好的解决方法。如果你有任何提示,将不胜感激。