如何在C ++中将UTF-16代理十进制转换为UNICODE

时间:2016-02-22 06:53:47

标签: c++ unicode utf-16 surrogate-pairs

我从参数中获得了一些字符串数据,例如��

这些是Unicode的UTF-16代理项对,表示为十进制。

如何将它们转换为Unicode代码点,例如" U + 1F62C"使用标准库?

1 个答案:

答案 0 :(得分:2)

您可以轻松地手动 。从高unicode点到代理对和后面的algorythm并不那么难。 UTF16上的维基百科页面说:

U + 10000到U + 10FFFF

    从代码点中减去
  • 0x010000,在0..0x0FFFFF范围内留下一个20位数字。
  • 前十位(0..0x03FF范围内的数字)被添加到0xD800以给出第一个16位代码单元或高代理,它将在0xD800..0xDBFF范围内。
  • 低十位(也在0..0x03FF范围内)被添加到0xDC00以提供第二个16位代码单元或低代理,它将在0xDC00..0xDFFF范围内。

这只是按位,和/或移位,可以简单地用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