从字符的 ASCII 代码点到 wstring

from ascii codepoint of character to wstring

本文关键字:wstring 代码 ASCII 字符      更新时间:2023-10-16

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

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 编码(。

存储在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);
}
}
}

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

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