D言語+Windows環境で日本語(Shift-JIS)を使ってエラーや文字化けが起きた場合の対処方法


はじめに

D言語を学び始めた頃に、文字化けでハマったことを思い出しながら、記事にしようと思います。

当時、私はD言語 に関する記事を読んで 私が求めていた言語仕様はこれかもしれない"Hello World!"のサンプルを読んで よし、やってみよう とチャレンジするものの、すぐに小石につまづくのでした。

環境情報

  • Windows 10
  • dmd v2.099.0

ソースコードの文字コードについて

"Hello World!"はわかったので、次に日本語を表示してみようと思い、次のソースコードを書きました。

sample1.d
import std.stdio;

void main()
{
  writeln("D言語の世界へようこそ");
}
コマンドプロンプト
D:\Dev>dmd sample1.d
sample1.d(5): Error: Outside Unicode code space
sample1.d(5): Error: Outside Unicode code space
sample1.d(5): Error: Outside Unicode code space
sample1.d(5): Error: Outside Unicode code space
sample1.d(5): Error: Invalid trailing code unit
sample1.d(5): Error: Outside Unicode code space
sample1.d(5): Error: Outside Unicode code space
sample1.d(5): Error: Outside Unicode code space
sample1.d(5): Error: Outside Unicode code space
sample1.d(5): Error: Outside Unicode code space
sample1.d(5): Error: Outside Unicode code space
sample1.d(5): Error: Outside Unicode code space
sample1.d(5): Error: Outside Unicode code space

コンパイルすると、めっちゃエラー出るんですけど・・・。

ソースコードの文字コードがShift-JISだと、このようなエラーが出力されます。
対処方法としては、ソースコードをUTF-8で保存すればよいだけです。

実行結果の文字化けについて

ソースコードをUTF-8にすることでコンパイルエラーはなくなりましたが、コマンドプロンプトで実行すると、文字化けが起きます。
当時、解決方法がわからず、ハマりました。

コマンドプロンプト
D:\Dev>dmd sample1.d

D:\Dev>sample1.exe
・、險隱槭・荳也阜縺ク繧医≧縺薙◎

文字化けの対処方法

その1 UTF-8→Shift-JISコード変換

sample2.dのように実装すれば、UTF-8からShift-JISへのコード変換が可能です。

sample2.d
import std.stdio;

string toSjis(string s)
{
  import std.conv;
  import std.utf;
  import std.windows.charset;
  
  return ( to!string(toMBSz(s)) );
}

void main()
{
  writeln("D言語の世界へようこそ".toSjis);
}

文字コード変換用関数toSjisを用意することで、正しく表示されました。

コマンドプロンプト
D:\Dev>dmd sample2.d

D:\Dev>sample2.exe
D言語の世界へようこそ

その2 コマンドプロンプトの文字コードを変更する

こちらの方法で文字化けを回避する手もあります。コマンドプロンプトの文字コードをUTF-8に設定するという逆転の発想となります。先ほど文字化けしていた sample1.exeが正しく表示されました。
Shift-JISでファイル出力したい等の要望がなければ、この方法もありだと思います。

コマンドプロンプト
D:\Dev>chcp 65001
Active code page: 65001

D:\Dev>sample1.exe
D言語の世界へようこそ

その3 Windows Terminalを使う

ここまでの対処方法は、当時も思いつきましたが、実はまだ問題があります。
以下のソースコード中の𝓓は unicode追加多言語面の文字、あと顔文字もあります。
これらの文字は、通常コマンドプロンプトでは表示できません。

sample3.d
import std.stdio;

void main()
{
  writeln("\x1b[31m𝓓\x1b[37m言語の世界へようこそ😏");
}

Windows Terminalを導入することで、これらの問題も解消できます。エスケープシーケンスで文字色も変えられます。

その4(番外編)

オンライン環境であれば、特に悩むこともなく表示可能です。

参考情報

文字コード変換について記事を書きましたので、紹介します。