1

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

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

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

4

1 回答 1

3

你可以很容易地用手把它。从高 unicode 点传递到代理对并返回的算法并不难。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
于 2016-02-22T09:58:50.983 回答