使用代码,我可以使用代码点字符的wstring。 如果codepoint> 65535采用错误的wstring。怎么做?
wstring giveWStringFromASCII(size_t i)
{
wchar_t character[]= {i,0};
return wstring(character);
}
答案 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::u16string
和std::u32string
来避免std::wstring
的可移植性问题。考虑尽可能使用它们。或者,至少,如果不使用第三方库,请考虑在处理UTF转换时使用std::wstring_convert
。