Zig言語でUTF-8の日本語を出力(Windows)
解決したいこと
Zig から派生した Zen 言語では Windows 上でも UTF-8 で書かれたソース(文字列)をなんの手を加えることもなく、コンソールに表示させることができますが、Zig for Windows では、コマンドプロンプトで予め「chcp 65001」としてUTF-8モードにしておかないと文字化けします。
以下のソースは、Zen言語で自動的に追加される「SetConsoleOutputCP」関数(Win32 API)を手動で追加したものです。mainの先頭で一回呼んでおけば、それ以降のコンソール出力がUTF-8を正常に受け付けるようになります。(chcp 932 の状態でも表示されます。また、chcp 932 の状態でも韓国語やアラビア語も表示できます)
const std = @import("std");
const windows = @import("std").os.windows;
const WINAPI = windows.WINAPI;
const BOOL = windows.BOOL;
const UINT = windows.UINT;
extern "kernel32" fn SetConsoleOutputCP(wCodePageID: UINT) callconv(WINAPI) BOOL;
pub fn main() anyerror!void {
_ = SetConsoleOutputCP(65001);
std.log.info("Zig の道へようこそ。\n道案内はこちらからどうぞ:\nhttps://ziglang.org/ja/\n", .{});
std.log.info("漢字(韓国語)=한자\n漢字(アラビア語)=كانجي\n", .{});
}
英語圏以外(でかつ Windowsのコンソールアプリ)なら必須の処理なので Zen 言語のように処理系が隠蔽してくれてもよさげに思いますが、「隠された処理」を嫌う Zig では取り込んでもらうのは無理かもしれません。
せめて、Linux や macOS とソースを同一化するために、「SetConsoleOutputCP」関数の宣言と呼び出しを Windows でない場合には削除したいのですが、どうすればよいのかわかりません。もしわかる人がいたら教えてください。
また、Zig for Windows で UTF-8 文字列を表示する他の良い方法があればそれでもかまいません。
よろしくお願いします。
追伸:
https://zenn.dev/javacommons/articles/de2a99ecf588f9
のコメントにあるように以下のコードで Windows と Ubuntu で同一ソースで日本語(UTF-8)を出力できました。
const builtin = @import("builtin");
const std = @import("std");
const windows = @import("std").os.windows;
const WINAPI = windows.WINAPI;
const BOOL = windows.BOOL;
const UINT = windows.UINT;
extern "kernel32" fn SetConsoleOutputCP(wCodePageID: UINT) callconv(WINAPI) BOOL;
pub fn main() anyerror!void {
switch (builtin.os.tag) {
.windows => _ = SetConsoleOutputCP(65001),
else => {}
}
std.log.info("Zig の道へようこそ。\n道案内はこちらからどうぞ:\nhttps://ziglang.org/ja/\n", .{});
}