在c ++中动态检测文件的字符集

时间:2017-05-11 12:30:27

标签: c++ unicode character-encoding utf icu

我正在尝试读取可能有任何charset / codePage的文件,但我没有设置哪个区域设置才能正确读取文件。

下面是我的代码片段,其中我尝试读取具有charset作为windows-1256的文件,但我想从正在读取的文件中动态获取字符集,以便我可以相应地设置区域设置。

std::wifstream input{ filename.c_str() };
std::wstring content{ std::istreambuf_iterator<wchar_t>(input1), std::istreambuf_iterator<wchar_t>() };
input.imbue(std::locale(".1256"));
contents = ws2s(content); // Convert wstring to CString

2 个答案:

答案 0 :(得分:2)

通常,单独使用纯文本文件的内容无法准确地做到这一点。通常你应该依赖一些外部信息。例如,如果使用HTTP下载文件,则应在响应头中接收编码。

某些文件可能包含有关文件格式指定的编码的信息。例如,XML:<?xml version="1.0" encoding="XXX"?>

如果文件以字节顺序标记开头,则可以检测到Unicode编码 - 这是可选的。

如果文件在文件结尾之前包含零字节(表示字符串终止符为窄字符),通常可以假设编码使用宽字符。同样,如果您发现两个连续的零对齐到2字节边界(在结束之前),那么编码可能是4个字节宽。

除此之外,您可以尝试根据某些字符的频率猜测编码。这可以有一些unintended consequences

答案 1 :(得分:1)

让我直言不讳地说:你不能

让我有资格说明:一个文件只是大量的0和1,卡在你的磁盘上。 charset是一种解释这些0和1的方法。 必须提供有关如何解释它们的信息,即通过指定字符集。

执行此操作的典型方法是编写标头以指定字符集。

这是一个html标题

<head>
  <title>Page Title</title>
  <meta charset="UTF-8">
</head>

如您所见,字符必须以这种或那种方式指定。

有一段时间,你确实看到一些流氓应用程序猜测一个字符集,他们经常会在字节分布上用一些启发式方法来做,但这不可靠并经常导致乱码。

作为旁注,请尝试使用here,其他人则轻描淡写地使用它。