С кодом ниже я могу взять wstring символа кодовой точки.
Если кодовая точка> 65535, принять неверную строку. Как это сделать?
wstring giveWStringFromASCII(size_t i)
{
wchar_t character[]= {i,0};
return wstring(character);
}
std::wstring
использования wchar_t
элементы. wchar_t
не является переносимым, так как использует 2 байта (в кодировке UTF-16) в Windows, но использует 4 байта (в кодировке UTF-32) на других платформах.
Код Unicode, хранящийся в size_t
может быть назначен как есть wchar_t
только на не-Windows платформах. На Windows один wchar_t
может обрабатывать только символы Юникода в диапазоне BMP (UCS-2) (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
, Подумайте об их использовании, когда это возможно. Или, по крайней мере, рассмотреть возможность использования std::wstring_convert
при работе с UTF-преобразованиями, если не используется сторонняя библиотека.
Других решений пока нет …