📌
【Zig】文字とコードポイントの相互変換
std.debug.print
でコードポイントを調べることもできる。1文字をシングルクォートで囲む。複数のコードポイントで構成される文字列は利用できない
const std = @import("std");
const print = std.debug.print;
pub fn main() !void {
print("{u}\n", .{ 0x3042 });
print("U+{X}\n", .{ 'あ' });
print("{}\n", .{ comptime_int == @TypeOf('あ')});
}
一般的なバイト列に関して std.unicode
の utf8Encode
と utf8Decode
を使う
const std = @import("std");
const print = std.debug.print;
const utf8Encode = std.unicode.utf8Encode;
const utf8Decode = std.unicode.utf8Decode;
pub fn main() !void {
var buf: [4]u8 = undefined;
_ = try utf8Encode(0x3042, buf[0..]);
const cp = try utf8Decode("あ");
print("{s}\n", .{ buf });
print("U+{X}\n", .{ cp });
}
文字からのコードポイントの変換に関してイテレーターを使うこともできる
const std = @import("std");
const print = std.debug.print;
const unicode = std.unicode;
pub fn main() !void {
const s = "あいうえお";
var it = (try unicode.Utf8View.init(s)).iterator();
const cp = it.nextCodepoint().?;
print("U+{X}\n", .{ cp });
}
utf8Decode
に関して補足。2、3、4バイト限定の utf8Decode2
、utf8Decode3
、utf8Decode4
が公開 API として利用できる。utf8ByteSequenceLength
は先行バイトをもとに文字のサイズを返す関数である。
const std = @import("std");
const print = std.debug.print;
const utf8ByteSequenceLength = std.unicode.utf8ByteSequenceLength;
const utf8Decode = std.unicode.utf8Decode;
const utf8Decode2 = std.unicode.utf8Decode2;
const utf8Decode3 = std.unicode.utf8Decode3;
const utf8Decode4 = std.unicode.utf8Decode4;
pub fn main() !void {
// 1バイト
print("{} バイト ", .{ try utf8ByteSequenceLength("a"[0]) });
print("U+{X}\n", .{ try utf8Decode("a") });
// 2バイト
print("{} バイト ", .{ try utf8ByteSequenceLength("α"[0]) });
print("U+{X}\n", .{ try utf8Decode2("α") });
// 3バイト
print("{} バイト ", .{ try utf8ByteSequenceLength("あ"[0]) });
print("U+{X}\n", .{ try utf8Decode3("あ") });
// 4バイト
print("{} バイト ", .{ try utf8ByteSequenceLength("🐶"[0]) });
print("U+{X}\n", .{ try utf8Decode4("🐶") });
}
Discussion