Как перебирать символы unicode в C++?
Я знаю, что для получения символа unicode в C++ я могу сделать:
std::wstring str = L"u4FF0";
Однако, что делать, если я хочу получить все символы в диапазоне от 4FF0 до 5FF0? Можно ли динамически построить символ unicode? Я имею в виду что-то вроде этого псевдокода:
for (int i = 20464; i < 24560; i++ { // From 4FF0 to 5FF0
std::wstring str = L"u" + hexa(i); // build the unicode character
// do something with str
}
Как бы я сделал это в C++?
3 ответа:
Тип wchar_t, содержащийся в wstring, является целочисленным типом, поэтому его можно использовать напрямую:
for (wchar_t c = 0x4ff0; c <= 0x5ff0; ++c) { std::wstring str(1, c); // do something with str }
Будьте осторожны, пытаясь сделать это с символами выше 0xffff, так как в зависимости от платформы (например, Windows) они не будут вписываться в wchar_t.
Если, например, вы хотите видеть блок смайликов в строке, вы можете создать суррогатные пары:
std::wstring str; for (int c = 0x1f600; c <= 0x1f64f; ++c) { if (c <= 0xffff || sizeof(wchar_t) > 2) str.append(1, (wchar_t)c); else { str.append(1, (wchar_t)(0xd800 | ((c - 0x10000) >> 10))); str.append(1, (wchar_t)(0xdc00 | ((c - 0x10000) & 0x3ff))); } }
Вы не можете увеличивать символы Юникода, как если бы это был массив, некоторые символы строятся из нескольких символов ' char (UTF-8) и нескольких символов 'WCHAR (UTF-16), что связано с диакритикой и т. д. Если вы действительно серьезно относитесь к этому вопросу, вы должны использовать API, такие как UniScribe или ICU.
Некоторые ресурсы для читать:
Http://en.wikipedia.org/wiki/UTF-16/UCS-2
Http://en.wikipedia.org/wiki/Precomposed_character
Http://en.wikipedia.org/wiki/Combining_character
Http://scripts.sil.org/cms/scripts/page.php?item_id=UnicodeNames#4d2aa980
Как насчет:
Обратите внимание, что код не был протестирован, поэтому он не может компилироваться как есть.for (std::wstring::value_type i(0x4ff0); i <= 0x5ff0; ++i) { std::wstring str(1, i); }
Кроме того, учитывая платформу, на которой вы работаете, символьная единица
wstring
может быть шириной 2, 4 или N байт - поэтому будьте намеренны в том, как вы ее используете.