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



我正在尝试读取可能具有任何字符集/代码页的文件,但我不知道要设置哪个语言环境才能正确读取文件。

下面是我的代码片段,其中我尝试读取字符集为 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

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

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

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

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

除此之外,您可以尝试根据某些字符的频率猜测编码。这可能会产生一些意想不到的后果。

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

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

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

这是一个 html 标头

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

如您所见,必须以某种方式指定字符集。

偶尔,您确实会看到一些流氓应用程序猜测字符集,他们经常对字节分布进行一些启发式操作,但这并不可靠,并且经常导致胡言乱语。

作为旁注,尝试在任何地方使用 UTF-8,其他的,轻描淡写地说,很混乱。

最新更新