Как преобразовать десятичную дробь UTF-16 в UNICODE при переполнении стека

Я получил некоторые строковые данные из параметра, такого как ��,

Это суррогатные пары UTF-16 Unicode, представленные в десятичном виде.

Как я могу преобразовать их в кодовые точки Unicode, такие как «U + 1F62C» со стандартной библиотекой?

1

Решение

Вы можете легко к этому рукой. Алгоритм перехода от высокой точки Unicode к суррогатной паре и обратно не так сложен. Страница Википедии на UTF16 говорит:

U + 10000 до U + 10FFFF

  • 0x010000 вычитается из кодовой точки, оставляя 20-битное число в диапазоне 0..0x0FFFFF.
  • Первые десять битов (число в диапазоне 0..0x03FF) добавляются к 0xD800, чтобы получить первую 16-битную кодовую единицу или старший суррогат, который будет в диапазоне 0xD800..0xDBFF.
  • Десять младших битов (также в диапазоне 0..0x03FF) добавляются к 0xDC00, чтобы получить вторую 16-битную кодовую единицу или младший суррогат, который будет в диапазоне 0xDC00..0xDFFF.

Это только поразрядно, и, или, и shift и могут быть тривиально реализованы в C или C ++.


Как вы сказали, что хотите использовать стандартную библиотеку, вы запрашиваете преобразование из двух 16-битных суррогатов UTF-16 в одну 32-битную кодовую точку Unicode, поэтому codecvt ваш друг, при условии, что вы можете скомпилировать в режиме C ++ 11 или выше.

Вот пример обработки ваших значений на архитектуре с прямым порядком байтов:

#include <iostream>
#include <locale>
#include <codecvt>

int main() {
std::codecvt_utf16<char32_t, 0x10ffffUL,
std::codecvt_mode::little_endian> cvt;
mbstate_t state;

char16_t pair[] = { 55357, 56842 };
const char16_t *next;

char32_t u[2];
char32_t *unext;

cvt.in(state, (const char *) pair, (const char *) (pair + 2),
(const char *&) next, u, u+1, unext);

std::cout << std::hex << (uint16_t) pair[0] << " " << (uint16_t) pair[1]
<< std::endl;
std::cout << std::hex << (uint32_t) u[0] << std::endl;

return 0;
}

Выход как и ожидалось:

d83d de0a
1f60a
2

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

Других решений пока нет …

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