Pracuję nad programem terminalowym obsługującym standard Unicode. Są pewne przypadki, w których muszę określić, ile kolumn terminalu zużyje, zanim wydrukuję. Niestety niektóre znaki mają szerokość 2 kolumn (chiński, itd.), Ale znalazłem this answer, który wskazuje na dobry sposób wykrywania znaków o pełnej szerokości poprzez wywołanie u_getIntPropertyValue() z biblioteki ICU.Jak wykryć szerokość napisu Unicode w terminalu?
Teraz próbuję przeanalizować znaki mojego łańcucha UTF8 i przekazać je do tej funkcji. Problem, który mam teraz, polega na tym, że u_getIntPropertyValue() oczekuje punktu kodowego UTF-32.
Jaki jest najlepszy sposób na uzyskanie tego z ciągu utf8? Obecnie próbuję zrobić to z boost :: locale (używane w innym miejscu w moim programie), ale mam problem z uzyskaniem czystej konwersji. Moje ciągi znaków UTF32 pochodzące z funkcji boost :: locale są wstępnie oznaczone numerem zero-width character, aby wskazać kolejność bajtów. Oczywiście mogę po prostu pominąć pierwsze cztery bajty ciągu, ale czy jest to czystszy sposób na zrobienie tego?
Oto mój obecny brzydki rozwiązanie:
inline size_t utf8PrintableSize(const std::string &str, std::locale loc)
{
namespace ba = boost::locale::boundary;
ba::ssegment_index map(ba::character, str.begin(), str.end(), loc);
size_t widthCount = 0;
for (ba::ssegment_index::iterator it = map.begin(); it != map.end(); ++it)
{
++widthCount;
std::string utf32Char = boost::locale::conv::from_utf(it->str(), std::string("utf-32"));
UChar32 utf32Codepoint = 0;
memcpy(&utf32Codepoint, utf32Char.c_str()+4, sizeof(UChar32));
int width = u_getIntPropertyValue(utf32Codepoint, UCHAR_EAST_ASIAN_WIDTH);
if ((width == U_EA_FULLWIDTH) || (width == U_EA_WIDE))
{
++widthCount;
}
}
return widthCount;
}
Jeśli używałeś ICU, dlaczego nie użyć go do konwersji utf8-to-utf32 też? –
Nie jestem zaznajomiony z ICU. Próbowałem użyć boost :: locale, aby odizolować mnie od większości złożoności. Czy istnieje prosty sposób na uzyskanie tego kodu UTF bezpośrednio z ICU? – KyleL
Nie jestem również obeznany z tym, ale wiem, że ma wszystko, czego ktoś chciał, z biblioteki unikodowej. Poświęć trochę czasu na google, a znajdziesz to. –