0

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

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

1 回答 1

1

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

存储在 a 中的 Unicode 代码点只能在非 Windows 平台上size_t按原样分配给 a 。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,为您处理这种类型的转换。

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

于 2017-07-26T22:49:26.883 回答