在C ++中动态检测文件的字符集
Detect charset of file dynamically in c++
我正在尝试读取一个可能包含 charset/codePage 的文件,但我不知道要设置哪个语言环境才能正确读取文件。
下面是我的代码片段,我在其中尝试读取一个字符集为 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
让我直言不讳地说:你不能
让我限定一下:一个文件只是大量的 0 和 1 卡在您的磁盘上。字符集是一种解释这些 0 和 1 的方法。 您必须提供有关如何解释它们的信息,即通过指定字符集。
一种典型的做法是编写 header 来指定字符集。
这是一个htmlheader
<head>
<title>Page Title</title>
<meta charset="UTF-8">
</head>
如您所见,字符集必须以一种或另一种方式指定。
偶尔,您确实会看到一些流氓应用程序猜测字符集,他们通常会通过一些关于字节分布的试探法来这样做,但这并不可靠,而且经常会导致乱码。
作为旁注,尝试使用UTF-8 everywhere,其他的,说得轻一点,很乱。
一般情况下,仅使用纯文本文件的内容是无法准确做到这一点的。通常你应该依赖一些外部信息。例如,如果文件是通过 HTTP 下载的,则应在响应 header.
中接收编码
某些文件可能包含有关文件格式指定的编码信息。 XML 例如:<?xml version="1.0" encoding="XXX"?>
.
如果文件以可选的字节顺序标记开头,则可以检测到 Unicode 编码。
如果文件在文件末尾之前包含一个零字节(这会将字符串终止符表示为窄字符),您通常可以假设编码使用宽字符。同样,如果您发现两个连续的零与 2 字节边界对齐(在结束之前),则编码可能是 4 字节宽。
除此之外,您可以尝试根据某些字符的出现频率来猜测编码。这可以有一些unintended consequences.
我正在尝试读取一个可能包含 charset/codePage 的文件,但我不知道要设置哪个语言环境才能正确读取文件。
下面是我的代码片段,我在其中尝试读取一个字符集为 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
让我直言不讳地说:你不能
让我限定一下:一个文件只是大量的 0 和 1 卡在您的磁盘上。字符集是一种解释这些 0 和 1 的方法。 您必须提供有关如何解释它们的信息,即通过指定字符集。
一种典型的做法是编写 header 来指定字符集。
这是一个htmlheader
<head>
<title>Page Title</title>
<meta charset="UTF-8">
</head>
如您所见,字符集必须以一种或另一种方式指定。
偶尔,您确实会看到一些流氓应用程序猜测字符集,他们通常会通过一些关于字节分布的试探法来这样做,但这并不可靠,而且经常会导致乱码。
作为旁注,尝试使用UTF-8 everywhere,其他的,说得轻一点,很乱。
一般情况下,仅使用纯文本文件的内容是无法准确做到这一点的。通常你应该依赖一些外部信息。例如,如果文件是通过 HTTP 下载的,则应在响应 header.
中接收编码某些文件可能包含有关文件格式指定的编码信息。 XML 例如:<?xml version="1.0" encoding="XXX"?>
.
如果文件以可选的字节顺序标记开头,则可以检测到 Unicode 编码。
如果文件在文件末尾之前包含一个零字节(这会将字符串终止符表示为窄字符),您通常可以假设编码使用宽字符。同样,如果您发现两个连续的零与 2 字节边界对齐(在结束之前),则编码可能是 4 字节宽。
除此之外,您可以尝试根据某些字符的出现频率来猜测编码。这可以有一些unintended consequences.