【问题标题】:from ascii codepoint of character to wstring从字符的ASCII码点到wstring
【发布时间】:2017-07-26 22:15:35
【问题描述】:

使用下面的代码,我可以获取代码点字符的 wstring。 如果 codepoint>65535 使用错误的 wstring。必须怎么做?

wstring giveWStringFromASCII(size_t i)
{
    wchar_t character[]= {i,0};
    return wstring(character);
}

【问题讨论】:

  • std::u32string 适合你吗?
  • 不,必须是来自代码点的 wstring > 65535, 0xffff
  • ASCII 和 > 65535?不可能的!你说的是 Unicode?​​span>
  • @manni66 -- ASCII 的最大值是 127;有一堆“扩展 ASCII”编码使用 128 到 255 之间的值。
  • 请用更完整的句子说话。我不知道你在问什么。

标签: c++ wstring codepoint


【解决方案1】:

std::wstring 使用 wchar_t 元素。 wchar_t 不可移植,因为它在 Windows 上使用 2 个字节(UTF-16 编码),但在其他平台上使用 4 个字节(UTF-32 编码)。

存储在size_t 中的 Unicode 代码点只能在非 Windows 平台上按原样分配给 wchar_t。在 Windows 上,单个 wchar_t 只能处理 BMP (UCS-2) 范围 (U+0000 - U+FFFF) 内的 Unicode 字符。更高的代码点必须编码为 2 个wchar_t 元素,在 UTF-16 中称为“代理对”。

您所展示的内容只能在非 Windows 平台上按原样工作。如果您需要支持多平台,您将不得不#ifdef相应的代码,例如:

std::wstring giveWStringFromCodepoint(size_t cp)
{
    #ifdef _WIN32

    wchar_t ch[2];
    if (cp < 0x10000)
    {
        ch[0] = (wchar_t) cp;
        return std::wstring(ch, 1);
    }
    else
    {
        cp -= 0x10000;
        ch[0] = (wchar_t) ((cp >> 10) + 0xD800);
        ch[1] = (wchar_t) ((cp & 0x3FF) + 0xDC00);
        return std::wstring(ch, 2);
    }

    #else

    wchar_t ch = (wchar_t) i;
    return std::wstring(&ch, 1);

    #endif
}

或者:

std::wstring giveWStringFromCodepoint(size_t cp)
{
    #if (WCHAR_MAX > 0xFFFF)

    wchar_t ch = (wchar_t) i;
    return std::wstring(&ch, 1);

    #else

    wchar_t ch[2];
    if (cp < 0x10000)
    {
        ch[0] = (wchar_t) cp;
        return std::wstring(ch, 1);
    }
    else
    {
        cp -= 0x10000;
        ch[0] = (wchar_t) ((cp >> 10) + 0xD800);
        ch[1] = (wchar_t) ((cp & 0x3FF) + 0xDC00);
        return std::wstring(ch, 2);
    }

    #endif
}

或者:

std::wstring giveWStringFromCodepoint(size_t cp)
{
    if (sizeof(wchar_t) > 2)
    {
        wchar_t ch = (wchar_t) i;
        return std::wstring(&ch, 1);
    }
    else
    {
        wchar_t ch[2];
        if (cp < 0x10000)
        {
            ch[0] = (wchar_t) cp;
            return std::wstring(ch, 1);
        }
        else
        {
            cp -= 0x10000;
            ch[0] = (wchar_t) ((cp >> 10) + 0xD800);
            ch[1] = (wchar_t) ((cp & 0x3FF) + 0xDC00);
            return std::wstring(ch, 2);
        }
    }
}

话虽如此,您最好使用第 3 方 Unicode 库(如 ICONV 或 ICU)来为您处理此类转换。

如果您使用的是 C++11 或更高版本,则可以使用 std::u16stringstd::u32string 来避免 std::wstring 的可移植性问题。尽可能考虑使用它们。或者,至少,在处理 UTF 转换时考虑使用 std::wstring_convert,如果不使用 3rd 方库的话。

【讨论】:

  • 我不会检查 Windows(实际上是 #ifdef _WIN32),而是检查 wchar_t 的大小 - 它更容易、更清晰、更正确。
  • 可以查看WCHAR_MAX的值。 #if WCHAR_MAX == 65535...#elif WCHAR_MAX == 4294967295...#else#error unsupported wchar_t size#endif.
  • 谢谢大家。所以取决于操作系统。
猜你喜欢
  • 1970-01-01
  • 2018-04-17
  • 2015-06-23
  • 2011-01-24
  • 1970-01-01
  • 2012-08-02
  • 2018-11-23
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多