スポンサーリンク
ICUライブラリでのutf16の扱い方を調べていてマクロがあることを知ったのでいくつか列挙しておきたい。
ICU 71.1:utf16.h File Reference
https://unicode-org.github.io/icu-docs/apidoc/dev/icu4c/utf16_8h.html
utf16文字からコードポイントを得る
#pragma warning(disable:4996) #include <iostream> #include <unicode/utf16.h> int main() { const char16_t* u16c = u"あいう"; char32_t u32c; FILE* fp = fopen("test.txt", "w"); U16_GET_UNSAFE(u16c, 0, u32c); fwrite(&u32c, 4, 1, fp); U16_GET_UNSAFE(u16c, 2, u32c); fwrite(&u32c, 4, 1, fp); fclose(fp); }
与えられたコードポイントが、utf16で何要素になるかを返す。返却値は 1 または 2。
std::u32string cc; // U16_LENGTH 与えられたu32がu16で何要素になるか int len; cc = U"a"; len = U16_LENGTH(cc[0]); printf("--- %d\n", len); // 1 utf16一文字 cc = U"あ"; len = U16_LENGTH(cc[0]); printf("--- %d\n", len); // 1 utf16一文字 cc = U"👨👩👧👦"; len = U16_LENGTH(cc[0]); printf("--- %d\n", len); // 2 結合文字の最初の一文字 cc = U"𠀋"; len = U16_LENGTH(cc[0]); printf("--- %d\n", len); // 2 サロゲートペア cc = U"𠀋𡚴"; len = U16_LENGTH(cc[0]); printf("--- %d\n", len); // 2 最初の一文字がサロゲートペア
U16_IS_SINGLE(c) utf16文字cが、サロゲートペアでなければtrue。
U16_IS_SURROGATE(c) utf16文字cが、サロゲートペアであればtrue。
U16_IS_SURROGATE_LEAD(c) utf16文字cが、上位サロゲートであればtrue。ただし、cがサロゲートペアであることが分かっている必要がある。
U16_IS_SURROGATE_TRAIL(c) utf16文字cが、下位サロゲートであればtrue。ただし、cがサロゲートペアであることが分かっている必要がある。
U16_IS_SINGLE | U16_IS_SURROGATE | U16_IS_SURROGATE_LEAD | U16_IS_SURROGATE_TRAIL | |
u"a"[0] | true | false | true | false |
u"あ"[0] | true | false | true | false |
u"👨👩👧👦"[0] | false | true | true | false |
u"𠀋"[0] | false | true | true | false |
u"a"[1] | true | false | true | false |
u"あ"[1] | true | false | true | false |
u"👨👩👧👦"[1] | false | true | false | true |
u"𠀋"[1] | false | true | false | true |
コードポイントから上位サロゲート(lead)、下位サロゲート(trail)を算出する
#pragma warning(disable:4996) #include <iostream> #include <unicode/utf16.h> int main() { // UTF32 //char32_t u32c = U'あ'; char32_t u32c = U'𠀋'; // char32->char16に変換したとき何文字になるかをチェック if (U16_LENGTH(u32c) == 2){
// utf16に変換したときサロゲートペアになる場合は上下サロゲートを算出 char16_t aa[2]; aa[0] = U16_LEAD(u32c); // 上位サロゲート aa[1] = U16_TRAIL(u32c); // 下位サロゲート // ファイル出力 FILE* fp = fopen("test.txt", "w"); fwrite(aa, 2, 2, fp); fclose(fp);
} else {
//サロゲートペアに変換する必要がなければコードユニット値がutf16文字
char16_t u16 = char16_t(u32c); // ファイル出力 FILE* fp = fopen("test.txt", "w"); fwrite(&u16, 2, 1, fp); fclose(fp);
} }