【问题标题】:How to Convert UTF-16 Surrogate Decimal to UNICODE in C++如何在 C++ 中将 UTF-16 代理十进制转换为 UNICODE
【发布时间】:2016-02-22 06:53:47
【问题描述】:

我从��等参数中得到了一些字符串数据。

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

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

【问题讨论】:

  • 我已尝试帮助您格式化您的问题,感谢您修复我的问题。随意继续这样做。至于标准库,恐怕还不够。
  • 你需要自己解析。

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


【解决方案1】:

您可以轻松地手动操作。从高 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

【讨论】:

  • codecvt 只需要在 C++ 2011 或更高版本中出现。如果您使用 Clang 或 gcc,请确保使用 -std=c++11 标志。如果实在用不上,就只能使用手工的方案了,因为标准库的方式是codecvt
  • 感谢我手工将 Surrogaet 转换为 Imogi 的十进制代码,但现在的新问题是如何将 imogi 的十进制代码转换为 Uinicode :)
猜你喜欢
  • 2020-06-24
  • 2020-02-06
  • 2021-06-15
  • 2010-11-16
  • 1970-01-01
  • 2018-01-22
  • 1970-01-01
  • 1970-01-01
  • 2012-02-22
相关资源
最近更新 更多