🍣
【C 言語】UTF-8 文字列の表現方法
動作の確認は LLVM 18 である (Zig 0.13.0)。文字列を収納する配列の型は uint8_t
(C99) か char8_t
(C23) にする。これらを利用できない場合は unsinged char
型にする。unsigned char
型や char
型は処理系によって振る舞いが変わるのでクロスプラットフォームを対象としたプログラムコードでは避ける
test.c
#include <stdio.h>
#include <stdint.h>
#include <uchar.h>
int main(void)
{
// C99 stdint.h
uint8_t str[] = "あいうえお";
// C23 uchar.h
char8_t str2[] = "かきくけこ";
// C99 以前
unsigned char str3[] = "さしすせそ";
printf("%s %s %s\n", str, str2, str3);
return 0;
}
文字列はユニコード、バイト列の16進数のエスケープシーケンス、数値で表現できる
#include <stdio.h>
#include <stdint.h>
int main(void)
{
uint8_t str[] = "あいう";
uint8_t str2[] = "\u3042\u3044\u3046";
uint8_t str3[] = "\U00003042\U00003044\U00003046";
uint8_t str4[] = "\xE3\x81\x82\xE3\x81\x84\xE3\x81\x86";
uint8_t str5[] = {0xE3, 0x81, 0x82, 0xE3, 0x81, 0x84, 0xE3,
0x81, 0x86, 0};
uint8_t str6[] = {'\xE3', '\x81', '\x82', '\xE3', '\x81',
'\x84', '\xE3', '\x81', '\x86', '\0'};
uint8_t str7[10];
str7[0] = 0xE3;
str7[1] = 0x81;
str7[2] = 0x82;
str7[3] = 0xE3;
str7[4] = 0x81;
str7[5] = 0x84;
str7[6] = 0xE3;
str7[7] = 0x81;
str7[8] = 0x86;
str7[9] = 0;
printf("%s\n%s\n%s\n%s\n%s\n%s\n%s\n", str, str2, str3, str4,
str5, str6, str7);
return 0;
}
C++23 の仕様の一部も利用できることも確認した
#include <stdio.h>
#include <stdint.h>
int main(void)
{
// https://en.cppreference.com/w/cpp/language/escape
uint8_t str[] = "\u{1F415}\u{1F408}\u{1F407}";
uint8_t str2[] = "\N{DOG}\N{CAT}\N{RABBIT}";
printf("%s\n%s\n", str, str2);
return 0;
}
バイト列の表記は次のコマンドで調べられる
> echo -n あいうえお | hexdump -e '35/1 "%02X " "\n"'
E3 81 82 E3 81 84 E3 81 86 E3 81 88 E3 81 8A
> echo -n あいうえお | od -tx1 -An
e3 81 82 e3 81 84 e3 81 86 e3 81 88 e3 81 8a
> echo -n あいうえお | od -tx1 -An | tr [:lower:] [:upper:]
E3 81 82 E3 81 84 E3 81 86 E3 81 88 E3 81 8A
コードポイントを調べるには uconv
もしくは uniname
を使う
> echo -n あいうえお | uconv -x Hex/Unicode; echo
U+3042U+3044U+3046U+3048U+304A
> echo -n あいうえお | LINES=35 uniname
character byte UTF-32 encoded as glyph name
0 0 003042 E3 81 82 あ HIRAGANA LETTER A
1 3 003044 E3 81 84 い HIRAGANA LETTER I
2 6 003046 E3 81 86 う HIRAGANA LETTER U
3 9 003048 E3 81 88 え HIRAGANA LETTER E
4 12 00304A E3 81 8A お HIRAGANA LETTER O
Discussion