昨日のテストで、文字化けしていましたが、これを対策します。
答えは簡単で、エンコードの問題でした。
まず、コンソールのエンコードを見てみます。
932、Shift-JISとなっています。これに対して、System.Consoleのエンコーディングを見てみます。
UTF-8となっています。つまり、UTF-8として出力されたものをShift-JISとして表示しようとしているので、おかしくなっていると考えられます。あわせてしまえばよいですね。一人でやってる分にはConsoleのエンコードを変えるという選択肢もあるかもしれません。ただ、そうしてしまうと個々の環境で設定が必要になってしまうため、コード側で対策しておきたいところです。なので、System.Consoleのエンコードを変えてみます。
var enc = System.Text.Encoding.GetEncoding(932); var writer = new System.IO.StreamWriter(Console.OpenStandardOutput(), enc); Console.SetOut(writer);
としたいところなのですが、実はこれだと動きません。
NotSupportedException No data is available for encoding 932. For information on defining a custom encoding, see the documentation for the Encoding.RegisterProvider method.
何やら、エラーがSystem.Text.Encoding.RegiterProviderメソッドを見ろといっています。ここの説明では
.NET Framework 4.61 つのエンコード プロバイダーが含まれています。 T:System.Text.CodePagesEncodingProvider、を行う、利用可能なエンコーディングでは使用できませんが、完全な .NET Framework に存在を.NET Framework 4.6です。既定では、.NET Framework 4.6のみ、Unicode エンコーディング、ASCII、およびコード ページ 28591 をサポートします。
この「のみ」にすこし違和感ありますが、日本語は含まれていないようです。28591は、西ヨーロッパ言語 (ISO)ですね。というわけで、そもそも、日本語は既定でサポートされていません。デスクトップ同様のサポートを確保するためには、System.Text.CodePagesEncodingProviderを利用してねーという内容ですかね。このクラスには、Instanceという静的なプロパティが一つ。これをエラーの内容に従って追加してみましょう。
System.Text.Encoding.RegisterProvider(System.Text.CodePagesEncodingProvider.Instance); var enc = System.Text.Encoding.GetEncoding(932); var writer = new System.IO.StreamWriter(Console.OpenStandardOutput(), enc); Console.SetOut(writer);
という感じにしてみました。いざ、実行!
あれ!きれいですね。何も出てこないとなるのですが、これはバッファにFlushがかからないために出てこなくなるようです。なので、AutoFlushを有効にしちゃいましょう。
System.Text.Encoding.RegisterProvider(System.Text.CodePagesEncodingProvider.Instance); var enc = System.Text.Encoding.GetEncoding(932); var writer = new System.IO.StreamWriter(Console.OpenStandardOutput(), enc); writer.AutoFlush = true; Console.SetOut(writer);
という感じにプロパティの設定を追加。再び!
無事に日本語を拝めました。注意として、ここの実装だけだと、強制的にShiftJISとしてしまうので、Linuxで動かしたときは、逆に文字化けしてしまう可能性があります。また、日本語ではないWindowsでも同じことが言えます。様々なプラットフォームで動かすためには、以下を考慮しておいてみるとよいのではないかと思います。
- 実行しているOSが、Windowsか?
- 日本語で動いているか?