私はユニコードをサポートしているターミナルベースのプログラムを開発中です。文字列が印刷されるまでに消費するターミナル列の数を特定する必要がある場合があります。残念ながら、いくつかの文字は2列幅(中国語など)ですが、全角文字を検出する良い方法を示すthis answerは、ICUライブラリからu_getIntPropertyValue()を呼び出すことによって検出されました。端末のユニコード文字列幅を検出する方法は?
私はUTF8文字列の文字を解析して、この関数に渡そうとしています。私が今行っている問題は、u_getIntPropertyValue()がUTF-32コードポイントを期待していることです。
utf8文字列からこれを取得する最も良い方法は何ですか?私は現在、boost :: locale(私のプログラムのどこかで使われています)でこれをやろうとしていますが、きれいな変換を得ることができません。 boost :: localeから来る私のUTF32文字列は、バイト順序を示すためにzero-width characterであらかじめ保留されています。明らかに、私は文字列の最初の4バイトをスキップすることができますが、これを行うためのよりクリーンな方法がありますか? n.m @
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に精通していません。私はboost :: localeを使用して、ほとんどの複雑さから私を保護しようとしていました。このutf32コードポイントをICUから直接取得する簡単な方法はありますか? – KyleL
私はそれにも慣れていませんが、ユニコードライブラリから誰もが望んでいたことをすべて知っています。 Googleで時間を過ごすと、それを見つけることができます。 –