从ascii字符的代码点到wstring

时间:2017-07-26 22:15:36

标签: c++ wstring codepoint

使用代码,我可以使用代码点字符的wstring。 如果codepoint> 65535采用错误的wstring。怎么做?

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

1 个答案:

答案 0 :(得分: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)范围内的Unicode字符(U + 0000 - U + FFFF)。较高的代码点必须编码为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);
        }
    }
}

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

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