Экранирование символов Юникода с помощью C / Stack Overflow

Мне нужно экранировать символы Юникода во входной строке в escape-последовательности UTF-16 или UTF-32. Например, входной строковый литерал "Eat, drink, 愛" следует избегать как "Eat, drink, \u611b", Вот правила в таблице сортов:

Побег | Кодовая точка Unicode


‘\ u’ HEX HEX HEX HEX | Кодовая точка Unicode в диапазоне от U + 0 до U + FFFF
включительно, соответствующий закодированному шестнадцатеричному значению.


‘\ U’ HEX HEX HEX HEX HEX HEX HEX HEX | Кодовая точка Unicode в диапазоне
U + 0 до U + 10FFFF включительно, соответствующий закодированному шестнадцатеричному

значение.


В общем, просто определить символы Юникода, поскольку второй байт равен 0, если ASCII:

L"a" = 97, 0

, который не сбежит. Для символов Unicode второй байт никогда не равен 0:

L"愛" = 27, 97

, который экранируется как \u611b, Но как мне определить строку UTF-32, поскольку ее нужно экранировать не так, как UTF-16 с 8 шестнадцатеричными числами?

Это не так просто, как просто проверить размер строки, так как символы UTF-16 являются многобайтовыми, например :

L"प्रे" = 42, 9, 77, 9, 48, 9, 71, 9

Мне поручено экранировать входные строковые литералы, такие как Eat, drink, 愛 и сохранить их на диск в их буквальном виде Eat, drink, \u611b (Пример UTF-16) Если моя программа находит символ UTF-32, она также должна экранировать их в виде\U8902611b (Пример UTF-32), но я не могу найти определенный способ узнать, имею ли я дело с UTF-16 или UTF-32 во входном байтовом массиве. Итак, как я могу надежно отличить UTF-32 от символов UTF-16 в пределах wchar_t строка или байтовый массив?

5

Решение

В вашем вопросе много вопросов, я постараюсь ответить на самые важные.

Q. У меня есть строка C ++, как "Eat, drink, 愛"это строка UT8-8, UTF-16 или UTF-32?
О. Это определяется реализацией. Во многих реализациях это будет строка UTF-8, но это не предусмотрено стандартом. Проконсультируйтесь с вашей документацией.

Q. У меня есть широкая строка C ++, как L"Eat, drink, 愛"это строка UT8-8, UTF-16 или UTF-32?
О. Это определяется реализацией. Во многих реализациях это будет строка UTF-32. В некоторых других реализациях это будет строка UTF-16. Ни то, ни другое не предусмотрено стандартом. Проконсультируйтесь с вашей документацией.

В. Как я могу иметь переносимые строковые литералы C ++ UT8-8, UTF-16 или UTF-32?
A. В C ++ 11 есть способ:

u8"I'm a UTF-8 string."u"I'm a UTF-16 string."U"I'm a UTF-32 string."

В C ++ 03 такой удачи нет.

Q. делает строку "Eat, drink, 愛" содержать хотя бы один символ UTF-32?
О. Нет таких вещей как символы UTF-32 (и UTF-16 и UTF-8). Есть UTF-32 и т. Д. строки. Все они содержат Символы Юникода.

Q. Какого черта является символом Unicode?
Это элемент набора кодированных символов, определенный стандартом Unicode. В программе на C ++ это может быть представлено различными способами, самый простой и простой одиночное 32-битное целое значение в соответствии с кодовой точкой персонажа. (Я игнорирую составные символы здесь и приравниваю «символ» и «кодовая точка», если не указано иное, для простоты).

Q. Учитывая символ Unicode, как я могу избежать этого?
А. Изучите его ценность. Если он между 256 и 65535, выведите 2-байтовую (4 шестнадцатеричную) escape-последовательность. Если оно больше 65535, выведите 3-байтовую (6 шестнадцатеричных) escape-последовательность. В противном случае распечатайте его как обычно.

Q. Учитывая строку в кодировке UTF-32, как я могу разложить ее на символы?
A. Каждый элемент строки (который называется кодовая единица) соответствует одному символу (кодовая точка). Просто возьми их один за другим. Ничего особенного не нужно делать.

В. Как получить строку в кодировке UTF-16, как я могу разложить ее на символы?
А. Значения (кодовые единицы) вне диапазон от 0xD800 до 0xDFFF соответствует символам Unicode с одинаковым значением. Для каждого такого значения выведите либо нормальный символ, либо 2-байтовую (4 шестнадцатеричную) escape-последовательность. Ценности в диапазон от 0xD800 до 0xDFFF сгруппирован в пары, каждая пара представляет отдельный символ (кодовую точку) в диапазоне от U + 10000 до U + 10FFFF. Для такой пары выведите 3-байтовую (6 шестнадцатеричных цифр) escape-последовательность. Чтобы преобразовать пару (v1, v2) в ее символьное значение, используйте следующую формулу:

c = (v1 - 0xd800) >> 10 + (v2-0xdc00)

Обратите внимание, что первый элемент пары должен находиться в диапазоне 0xd800..0xdbff, а второй — в 0xdc00..0xdfff, в противном случае пара не сформирована.

В. Как получить строку в кодировке UTF-8, как я могу разложить ее на символы?
О. Кодировка UTF-8 немного сложнее, чем кодировка UTF-16, и я не буду здесь ее подробно описывать. В сети есть много описаний и примеров реализации, посмотрите их.

Q. Что случилось с моим L «प्रे» строка?
О. Это составной символ, который состоит из четырех кодовых точек Unicode: U + 092A, U + 094D, U + 0930, U + 0947. Обратите внимание, что это не то же самое, что высокий код, представленный суррогатной парой. как подробно описано в части ответа UTF-16. Это тот случай, когда «символ» не совпадает с «кодовой точкой». Избегайте каждого кода отдельно. На этом уровне абстракции вы имеете дело с точками кода, а не с реальными символами. Персонажи вступают в игру, когда вы, например, отображать их для пользователя или вычислять их положение в печатном тексте, но не при работе с кодировками строк.

11

Другие решения


По вопросам рекламы [email protected]