Chapter 04

Windows で UTF8 を扱う場合の2つのアプローチ

zetamatta
zetamatta
2021.02.07に更新

そんな Windows で UTF8 を扱おうとすると、2つのアプローチがあります。

  • 言語のライブラリ層で、UTF8 を UTF16 に変換して、Unicode系APIを使う
    • Cygwin、Go言語などがこの方法をとっている
    • アプリケーションはコードページを気にしなくてよくなる
      • なぜなら Unicode API は UTF16 しか取らないからコードページ関係ない
    • ただし、CMD.EXE がサポートしていない
      • バッチファイルが UTF16 で書けないので、どのコードページでも動作するバッチファイルが書けない
  • コードページを 65001 (UTF8) に切り替えて、ANSI系APIを使う
    • 一つのフォントは一つのコードページにしか属せない (過去形)
      • 日本語環境で chcp 65001 などでコードページを切り替えても日本語フォントが利用できない (過去形)
      • Windows10 の最近のアップデートでは、1フォント1コードページという縛りがなくなったらしく、「chcp 65001」の後も、引き続き、それまで使っていたフォントが利用できるようになった。すばらしい

さて、ANSI系APIで使用するコードを指定する「コードページ」ですが、実は三種類あるようです。

  • アクティブなコードページ(定数 CP_ACPで指定される)
  • スレッドのコードページ(定数 CP_THREAD_ACPで指定される)
  • コンソールのコードページ (API GetConsoleCP() で得られる)

ほとんどの場合は CP_ACP でも CP_THREAD_CP でも、どっち使ってても大丈夫なんですが(ほんとか?)、子プロセスで CMD.EXE を呼び出すような場合については、その CMD.EXE はスレッドのコードページではなく「コンソールのコードページ」で動作する(参考:problem : batchfile arg UTF-8 data broken. · Issue #322 · zetamatta/nyagos)ことが確認されています。なので、プログラムの中からバッチファイルを生成して実行する場合は注意が必要です。