CでUTF-8を扱う

今日はC言語で、UTF-8で文字数を数えるプログラムを書こうとしてつまづいた。
簡単そうで意外といいヒントが見つからない。Googleで検索しようにもいい検索語句が頭に浮かばない。
いちいち文字コード変換するとパフォーマンス上の問題が出てきてしまう。
色々と調べたつもりだったが、なかなか汎用的なライブラリが見つからない。
とりあえずは、最上位ビットを調べて、0が出てくるまでビットシフトしながらシフトした数を数えると言う、なんともパフォーマンス的に情けない解決策で乗り切った。

それが、夜になって、色々と適当な語句で検索していたら次のコードが見つかった。

/* Array of skip-bytes-per-initial character.
*/
GLIB_VAR const gchar * const g_utf8_skip;
#define g_utf8_next_char(p) (char *)((p) + g_utf8_skip[*(guchar *)(p)])

static const gchar utf8_skip_data[256] = {
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,5,5,5,5,6,6,1,1
};
const gchar * const g_utf8_skip = utf8_skip_data;

これは
http://dev.ariel-networks.com/Members/inoue/utf8-handling
からの引用。
これならパフォーマンス的な問題もないし、エンバグの心配もほとんどない。
原始的な力技にも見えるが、いや、やっぱり頭のいい人はいるもんだ。

次にまた検索しようとして見つけられなくなると困るので、ここに貼り付けておく。

ブログ気持玉

クリックして気持ちを伝えよう!

ログインしてクリックすれば、自分のブログへのリンクが付きます。

→ログインへ

なるほど(納得、参考になった、ヘー)
驚いた
面白い
ナイス
ガッツ(がんばれ!)
かわいい

気持玉数 : 0

この記事へのコメント

この記事へのトラックバック