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

C++ 如何在C+中将UTF-16代理十进制转换为UNICODE+;,c++,unicode,utf-16,surrogate-pairs,C++,Unicode,Utf 16,Surrogate Pairs,我从参数中获得了一些字符串数据,例如�� 这些是Unicode的UTF-16代理项对,表示为十进制 如何使用标准库将它们转换为Unicode代码点,如“U+1F62C”?您可以轻松地手动转换。从高unicode点传递到代理项对并返回的算法并不难。维基百科的页面上写着: U+10000至U+10FFFF 从代码点减去0x010000,留下一个范围为0..0x0FFFFF的20位数字 将前十位(范围为0..0x03FF的数字)添加到0xD800,以给出第一个16位代码单元

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

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

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

您可以轻松地手动转换。从高unicode点传递到代理项对并返回的算法并不难。维基百科的页面上写着:

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代码点,因此
codevt
是您的朋友,前提是您可以在C++11或更高模式下编译

下面是一个在little endian体系结构上处理您的值的示例:

#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;
}

我已尝试帮助您设置问题的格式,感谢您修复我的修复。请继续这样做。至于标准库,恐怕不够。您需要自己解析。<代码> CODECVT < /C> >只需要用于C++ 2011或更高版本。如果使用Clang或gcc,请确保使用
-std=c++11
标志。如果您真的不能使用它,您将不得不使用手动解决方案,因为标准的库方式是
codecvt
。Thansk手动将代理集转换为Imogi的十进制代码,但现在的新问题是如何将Imogi的十进制代码转换为Uinicode:)