GLib の g_utf8_to_ucs4_fast()
をつかう
UTF-8 の文字列から Unicode のコードポイントを取得するには、UTF-8 を UTF-32 (UCS4) に変換してあげれば良い。
iconv(3)
をつかってもいいけど、GLib に g_utf8_to_ucs4_fast()
というそのものズバリな関数があったのでそれを使ってやってみた。
ソースコード
utf8_to_codepoint.c
#include <stdio.h>
#include <glib.h>
int main (int argc, char* argv[]) {
// 引き数が渡されてなかったら終了
if (argc < 2) {
fprintf(stderr, "usage: %s text\n", argv[0]);
return 1;
}
// 引き数として渡された文字列を代入
char* utf8_text = argv[1];
// テキストの文字数を取得
glong length = g_utf8_strlen(utf8_text, -1);
// UCS4に変換
gunichar* codepoints = g_utf8_to_ucs4_fast(utf8_text, -1, NULL);
// 1文字づつ code point を出力
for (int i = 0; i < length; i++) {
printf("[U+%04X] ", codepoints[i]);
}
printf("\n");
// 終了処理
g_free(codepoints);
return 0;
}
メインの部分は下記になります。
// UCS4に変換
gunichar* codepoints = g_utf8_to_ucs4_fast(utf8_text, -1, NULL);
コンパイル(OS X の場合)
glib が入ってなかったら brew
でインストール
$ brew install glib
コンパイルします
$ gcc -Wall -I/usr/local/include/glib-2.0 -I/usr/local/lib/glib-2.0/include -lglib-2.0 -o utf8_to_codepoint utf8_to_codepoint.c
結果
$ ./utf8_to_codepoint "UTF-8の文字列を変換"
[U+0055] [U+0054] [U+0046] [U+002D] [U+0038] [U+306E] [U+6587] [U+5B57] [U+5217] [U+3092] [U+5909] [U+63DB]
無事、Unicode のコードポイントが取得できました。
↓サロゲートペアもOK
$ ./utf8_to_codepoint "????"
[U+2000B] [U+2123D] [U+2131B] [U+2146E]
g_utf8_to_ucs4_fast()
について
書式
#include <glib.h>
gunichar* g_utf8_to_ucs4_fast(const gchar *str,
glong len,
glong *items_written);
>
>### 説明
> 有効なUTF-8の入力を想定して、UTF-8文字列から32ビット固定幅の UCS-4に変換します。この機能は、`g_utf8_to_ucs4()` より約2倍の処理速度ですが、入力値のエラーチェックをしません。変換された文字列の末尾に'\0'が追加されます。
>
>__`str`__ : UTF-8 でエンコーディングされた文字列。
>
>__`len`__ : `str` の有効長として使用。0 以下の場合は、文字列の有効長はヌル文字までとなります。
>
>__`items_written`__ : 結果をストアするポインタか NULL を指定。(省略可)
>
>__戻り値__ : 新しく割り当てられた UCS-4 文字列へのポインタ。この値は、`g_free()` で開放する必要があります。
## 参考
* [g_utf8_to_ucs4()](https://developer.gnome.org/glib/stable/glib-Unicode-Manipulation.html#g-utf8-to-ucs4)
* [超初心者のための Unicode(ユニコード) 入門](http://bearmini.net/blog/View.aspx?bid=1&aid=99)
* [UTF-32 (UCS4) - Wikipedia](http://ja.wikipedia.org/wiki/UTF-32)
以上。