1

在 Visual Studio /C++ 中声明了一个 wstring c 并用代理对填充它(Unicode 0001F01C = Mahong tile)

std::cout << std::hex << 16;                    
std::cout << "Hello World!\n";
std::wstring c = L"\U0001F01C";             
wchar_t* ctest = &c[0];
std::cout << "Checking value: " << *ctest << ".." <<  endl;

当我打印出我希望得到这个 Unicode Number 的值时。但相反,我得到d83c

谁能告诉我为什么我没有得到 Unicode 值?

10Hello World!
Checking value: d83c..
4

1 回答 1

2

您只需执行创建 UTF-16 代理对的相反操作。

U+10000 至 U+10FFFF

从代码点中减去 0x010000,在 0..0x0FFFFF 范围内留下一个 20 位数。

前十位(0..0x03FF 范围内的数字)被添加到 0xD800 以给出第一个 16 位代码单元或高代理,它将在 0xD800..0xDBFF 范围内。

低十位(也在 0..0x03FF 范围内)被添加到 0xDC00 以提供第二个 16 位代码单元或低代理,它将在 0xDC00..0xDFFF 范围内。

要将代理对重组为 Unicode 代码点,只需执行相反的操作:

#include <cstdint>
#include <iostream>
#include <string>

int main() {
    std::cout << std::hex << 16 << "\n";
    std::cout << "Hello World!\n";
    std::u16string c = u"\U0001F01C";
    char16_t* ctest = &c[0];
    std::cout << "Checking value: " << *ctest << ".." <<  "\n";
    std::cout << "Checking value: " << ((static_cast<std::uint32_t>(ctest[0] & 0x03FF) << 10) | (ctest[1] & 0x03FF) | 0x10000U) << ".." <<  "\n";
}
于 2021-08-23T13:04:38.287 回答