如何读取 UTF-16 文件并将其内容与用十六进制值定义的 wchar_t* 字符串文字进行比较

How to read a UTF-16 file and compare it's contents to a wchar_t* string literal defined with hex values

我有一个 UTF-16(或 UCS-2,并不重要,因为据我所知它是 UTF-16 LE)编码的文件,我从这里下载:http://www.humancomp.org

我想将该文件的内容读入 std::wstring,这是我的第一个问题:我还不能正确读取该文件。读取的数据好像总是乱七八糟

其次,我想将读取的 std::wstringconst wchar_t* 字符串文字进行比较。在这里,我遇到了第二个问题:如何通过十六进制值指定 wchar_t 内容?

我想将其转换为 const wchar_t* 字符串文字的文件具有以下字节(从十六进制编辑器中复制)

FE FF 05 31 05 65 05 81 05 65 05 70 05 6B 00 20 05 6B 05 74 00 20 05 6C 05 61 05 7E 00 20 00 3F 05 82 05 72 05 6B 05 65 00 20 05 6C 05 61 05 7E 05 61 05 80 05 61 05 80 00 2C 00 0D 00 0A 05 3F 05 75 05 61 05 65 05 62 05 7D 00 20 05 79 05 7F 05 61 05 75 05 6B 00 20 05 6F 05 61 05 7D 05 6F 05 61 05 6E 05 6B 00 20 05 74 05 70 05 63 05 6B 05 65 00 2E 00 2E 00 2E 00 0D 00 0A 05 31 05 75 05 65 05 7A 05 70 05 7D 00 20 05 6F 00 3F 05 82 05 66 05 70 05 6B 00 20 05 74 05 70 05 6F 05 65 00 20 05 6B 05 65 05 6E 00 20 00 3F 05 61 05 7E 05 61 05 7F 05 80 00 2C 00 0D 00 0A 05 31 05 75 05 65 05 7A 05 70 05 7D 00 20 05 6F 00 3F 05 82 05 66 05 70 05 6B 00 20 00 3F 05 61 05 7E 05 61 05 7F 05 61 05 6C 00 20 05 74 05 70 05 6F 05 6B 05 65 05 89

当然,我不能用它来初始化字符串文字。我试图将其转换为十六进制值并应用 reinterpret_cast 以获得 const wchar_t*

reinterpret_cast<const wchar_t*>("\xFE\xFF\x05\x31\x05\x65\x05\x81\x05\x65\x05\x70\x05\x6B\x00\x20\x05\x6B\x05\x74\x00\x20\x05\x6C\x05\x61\x05\x7E\x00\x20\x00\x3F\x05\x82\x05\x72\x05\x6B\x05\x65\x00\x20\x05\x6C\x05\x61\x05\x7E\x05\x61\x05\x80\x05\x61\x05\x80\x00\x2C\x00\x0D\x00\x0A\x05\x3F\x05\x75\x05\x61\x05\x65\x05\x62\x05\x7D\x00\x20\x05\x79\x05\x7F\x05\x61\x05\x75\x05\x6B\x00\x20\x05\x6F\x05\x61\x05\x7D\x05\x6F\x05\x61\x05\x6E\x05\x6B\x00\x20\x05\x74\x05\x70\x05\x63\x05\x6B\x05\x65\x00\x2E\x00\x2E\x00\x2E\x00\x0D\x00\x0A\x05\x31\x05\x75\x05\x65\x05\x7A\x05\x70\x05\x7D\x00\x20\x05\x6F\x00\x3F\x05\x82\x05\x66\x05\x70\x05\x6B\x00\x20\x05\x74\x05\x70\x05\x6F\x05\x65\x00\x20\x05\x6B\x05\x65\x05\x6E\x00\x20\x00\x3F\x05\x61\x05\x7E\x05\x61\x05\x7F\x05\x80\x00\x2C\x00\x0D\x00\x0A\x05\x31\x05\x75\x05\x65\x05\x7A\x05\x70\x05\x7D\x00\x20\x05\x6F\x00\x3F\x05\x82\x05\x66\x05\x70\x05\x6B\x00\x20\x00\x3F\x05\x61\x05\x7E\x05\x61\x05\x7F\x05\x61\x05\x6C\x00\x20\x05\x74\x05\x70\x05\x6F\x05\x6B\x05\x65\x05\x89");

但这不起作用。它给了我虚假数据。

我也试过直接创建一个 wchar_t 字符串文字:

L"\xFEFF\x0531\x0565\x0581\x0565\x0570\x056B\x0020\x056B\x0574\x0020\x056C\x0561\x057E\x0020\x003F\x0582\x0572\x056B\x0565\x0020\x056C\x0561\x057E\x0561\x0580\x0561\x0580\x002C\x000D\x000A\x053F\x0575\x0561\x0565\x0562\x057D\x0020\x0579\x057F\x0561\x0575\x056B\x0020\x056F\x0561\x057D\x056F\x0561\x056E\x056B\x0020\x0574\x0570\x0563\x056B\x0565\x002E\x002E\x002E\x000D\x000A\x0531\x0575\x0565\x057A\x0570\x057D\x0020\x056F\x003F\x0582\x0566\x0570\x056B\x0020\x0574\x0570\x056F\x0565\x0020\x056B\x0565\x056E\x0020\x003F\x0561\x057E\x0561\x057F\x0580\x002C\x000D\x000A\x0531\x0575\x0565\x057A\x0570\x057D\x0020\x056F\x003F\x0582\x0566\x0570\x056B\x0020\x003F\x0561\x057E\x0561\x057F\x0561\x056C\x0020\x0574\x0570\x056F\x056B\x0565\x0589"

这又一次以虚假数据告终。我什至不确定这是否是指定 wchar_t 数据的正确方法 - 组合 2 个字节?

这是在 Remy Lebeau 的评论帮助下实现的解决方案:

// BOM: \xFEFF
auto utf16raw = L"\x0531\x0565\x0581\x0565\x0570\x056B\x0020\x056B\x0574\x0020\x056C\x0561\x057E\x0020\x003F\x0582\x0572\x056B";
std::wstring utf16str{utf16raw};

BOM 必须从字符串中删除。 例如,UTF-16 字符串 utf16str 可以使用 UTF-8 CPP library available on Sourceforge 转换为 UTF-8 编码字符串(反之亦然)。