使用下面的代码,我可以获取代码点字符的 wstring。如果 codepoint>65535 使用错误的 wstring。必须怎么做?
wstring giveWStringFromASCII(size_t i)
{
wchar_t character[]= {i,0};
return wstring(character);
}
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 方库的话。