我正在研究一個基於終端的程序,它有unicode支持。在某些情況下,我需要確定一個字符串在打印之前會消耗多少終端列。不幸的是,有些字符是2列(中文等),但是我發現this answer表明檢測全角字符的好方法是通過調用ICU庫中的u_getIntPropertyValue()。如何檢測終端中的unicode字符串寬度?
現在我試圖解析我的UTF8字符串的字符,並將它們傳遞給此函數。我現在遇到的問題是,u_getIntPropertyValue()需要一個UTF-32代碼點。
什麼是從utf8字符串獲取這個最好的方法?我目前正在嘗試使用boost :: locale(在我的程序中的其他地方使用)執行此操作,但是我無法獲得乾淨的轉換。來自boost :: locale的我的UTF32字符串前面加上zero-width character來表示字節順序。顯然,我可以跳過字符串的前四個字節,但有沒有更清晰的方法來做到這一點?
這是我目前的醜陋的解決方案:
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;
}
如果您已經使用ICU,爲什麼不使用它的UTF8到UTF32轉換呢? –
我對ICU不熟悉。我試圖使用boost :: locale來隔離大多數複雜性。有沒有一種簡單的方法可以直接從ICU獲得這個utf32代碼點? – KyleL
我對它並不熟悉,但我知道它擁有任何人從unicode庫中想要的一切。花一些時間與谷歌,你會發現它。 –