2015-07-21 6 views
0

У меня есть файл в UTF-16 (или UCS-2, на самом деле не имеет значения, так как это UTF-16 LE, насколько я знаю): http://www.humancomp.orgКак прочитать файл UTF-16 и сравнить его содержимое с строковым литералом wchar_t *, определенным с шестнадцатеричными значениями

Я хотел бы прочитать содержимое этого файла в std::wstring, что является моей первой проблемой: я не смог прочитать файл еще не завершен. Чтение данных всегда кажется перепутанным.

Во-вторых, я хотел бы сравнить прочитанный std::wstring с строковым литералом const 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 байта?

+2

Байт вашего файла находится в ** UTF-16BE ** (о чем свидетельствует наличие спецификации UTF-16BE). Если ваш строковый литерал находится в ** UTF-16LE **, вам нужно будет сделать преобразование, прежде чем вы сможете сравнить его. Ваш 'reinterpret_cast' для сырых литералов в порядке, за исключением того, что вы получаете мусор в конце, потому что вы не включаете нулевой ограничитель в UTF-16:' \ x00 \ x00'. Ваш 'L" ... "' literal корректно завершен нулем. –

+0

Чтобы прочитать кодированный файл UTF-16BE в 'std :: wstring', используйте' std :: wifstream', который был 'imbue()' 'ed с объектом 'std :: locale', который представляет UTF-16BE , Если вы используете C++ 11, вы можете создать 'std :: locale', который использует класс' std :: codecvt_utf16' с включенным флагом 'std :: consume_header', поэтому он будет учитывать спецификацию. –

ответ

0

Вот решение, которое было достигнуто с помощью замечания Реми Лебо:

// 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}; 

спецификация должна быть исключена из строки. Строка UTF-16, utf16str может быть преобразована в кодированную строку UTF-8 (и наоборот) с помощью, например, UTF-8 CPP library available on Sourceforge.

+1

Если разрешено C++ 11 или выше, стандартная библиотека сама по себе - это все, что необходимо для преобразования между UTF-8 и UTF-16. См. Http://stackoverflow.com/a/18597384/6345 для справки. –

 Смежные вопросы

  • Нет связанных вопросов^_^