Как правильно инициализировать строку широких символов? - PullRequest
3 голосов
/ 22 апреля 2019

Я пытаюсь выяснить широкие символы в c.Например, я проверяю строку, содержащую одну букву «Ē», которая кодируется как c492 в utf8.

char* T1 = "Ē";
//This is the resulting array { 0xc4, 0x92, 0x00 }

wchar_t* T2 = L"Ē";
//This is the resulting array { 0x00c4, 0x2019, 0x0000 }

Я ожидал, что второй массив будет {0xc492, 0x0000}, вместо этого он содержитдополнительный персонаж, который просто тратит пространство по моему мнениюМожет кто-нибудь помочь мне понять, что происходит с этим?

Ответы [ 2 ]

6 голосов
/ 22 апреля 2019

То, что вам удалось здесь сделать, это моджибаке. Ваш исходный код написан на UTF-8, но он был интерпретирован в кодовой странице Windows 1252 (т.е. исходный набор символов компилятора был CP1252 ).

Содержимое широкой строки - это кодовая страница Windows 1252 символов байтов UTF-8 0xC4 0x92, преобразованных в UCS-2. Самый простой выход - просто использовать вместо него escape:

wchar_t* T2 = L"\x112";

или

wchar_t* T2 = L"\u0112";

Большая проблема в том, что, насколько мне известно, ни в C, ни в C ++ не существует механизма для указания исходного набора символов в самом коде, поэтому это всегда параметр или параметр, внешний по отношению к чему-либо, что вы можете легко скопировать и вставить.

4 голосов
/ 22 апреля 2019

Ваш компилятор неправильно интерпретирует файл исходного кода (который сохраняется как UTF-8) как Windows-1252 (обычно называемый ANSI). Он не интерпретирует последовательность байтов C4 92 как односимвольную строку UTF-8 "Ē", а как двухсимвольную строку Windows-1252 "Ä’". Кодовая точка Unicode "Ä" - это U + 00C4, а кодовая точка Unicode "’" - U + 2019. Это именно то, что вы видите в вашей строке широких символов.

8-битная строка работает только потому, что неправильная интерпретация строки не имеет значения, так как она не преобразуется во время компиляции. Компилятор считывает строку как Windows-1252 и выдает строку как Windows-1252 (поэтому ему не нужно ничего преобразовывать, и считает, что оба являются «Ä»). Вы интерпретируете исходный код и данные в двоичном виде как UTF-8, поэтому вы считаете, что оба значения "Ē".

Чтобы компилятор обрабатывал ваш исходный код как UTF-8, используйте переключатель / utf-8 .

Кстати: правильная кодировка UTF-16 (которая является кодировкой, используемой MSVC для строк широких символов), наблюдаемая в строке широких символов, не {0xc492, 0x0000}, но {0x0112, 0x0000}, поскольку "Ē" - это U+0112.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...