質問: windows 10 pro vscode バージョン 1.25.1 vscodeのターミナルで日本語が文字化けします。ユーザー設定で `"files.autoGuessEncoding": true` としたのですが直りません。どうすればいいのでしょうか。 プログラミング初心者なので変なこと言ってたらすみません。 追記 -- `"files.encoding": "shiftjis"`を追記してみたらエディタもターミナルも文字化けしました。 ![文字化けしている様子のスクリーンショットです](https://i.stack.imgur.com/ho4pb.png) `"terminal.integrated.shellArgs.windows": ["-NoExit","chcp 65001"]`を設定に追加すると文字が出力されませんでした。 ![設定を変えると出力がでなくなった様子のスクリーンショットです](https://i.stack.imgur.com/b5md1.png) ちゃんと動くプログラムと動かないプログラムがあります。 ![動くプログラムの例です](https://i.stack.imgur.com/TF1uQ.png) 3枚目の画像の"\n"をendlに変えても大丈夫です。 ![画像の説明をここに入力](https://i.stack.imgur.com/WgbXZ.png) また、ついさっきから新しくプログラムを書こうとしたら、iostream file not foundというような表示が出されます。それでも正しくコンパイルされて実行されます。英字は出力されますが日本語は出力されません。 ![画像の説明をここに入力](https://i.stack.imgur.com/JUrL6.png) ![画像の説明をここに入力](https://i.stack.imgur.com/Q1erZ.png) ![画像の説明をここに入力](https://i.stack.imgur.com/XVGWy.png)
回答: MinGW64 GCCを使用しているという前提で話します。Visual Studio (Visual C++)の場合はまた事情が異なります。 混乱しないように`"files.encoding"`、 `"terminal.integrated.shellArgs.windows"`、 `"files.autoGuessEncoding"`の設定は全て削除し、Visual Studio Codeを再起動しておいてください。 ソースコードは**UTF-8**にしてください(Visual C++でもコンパイルしたい、PowerShell上でソースコードを見たいと言った場合は、**UTF-8 with BOM**にしてください)。あとはコンパイル時に`-fexec-charset=CP932`オプションを付けることでうまくいきます(gccとg++ともに)。 ``` g++ -fexec-charset=CP932 hello.cpp ``` 以下、解説です。 C/C++には標準の文字コードと言ったものは存在しません。そのため、コンパイル時に正しい文字コードを指定しないとうまく動作しない場合があります。ややこしいのが、三つの文字コードが別々に使われると言うことです。それらは次の通りです。 1. ソースコード自身の文字コード 2. コンパイルされたバイナリ上での文字列リテラル(`"..."`)の文字コード 3. コンパイルされたバイナリ上でのワイド文字列リテラル(`L"..."`)の文字コード 1.から2.や3へはコンパイラが文字コードを自動的に変換します。これらの文字コードが何であるかは環境やコンパイラによって違います。 MinGW64 GCCの場合 1. UTF-8 (BOM付きの場合も可) 2. UTF-8 3. UTF-16LE Visual C++の場合 1. ファイルの先頭にBOMがない場合はロケール依存(日本語ならCP932) ファイルの先頭にBOMがある場合はBOMによる自動判別(UTF-8、UTF-16LE、UTF-16BE) 2. ロケール依存(日本語ならCP932) 3. UTF-16LE もう一つ注意すべき事は`printf`や`iostream`等の動作です。これらは文字列(`char *`)を扱いますが、ロケールによって文字コード変換するという動作はおこなわず、データをそのまま出力します。そのため、文字列自体の文字コードと出力先の文字コードが合っていなければ、文字化けなどが発生することになります。(ワイド文字列の出力はロケールに合わせて文字コード変換等が行われる場合があります) そして、Visual Studio Codeの統合ターミナルでのPowerShellも文字コードをもっており、デフォルトはロケール依存(日本語ならCP932)となっています。つまり、文字化けの原因は、2.のコンパイルされたバイナリ上での文字列リテラルの文字コードとターミナルでの文字コードが一致していないと言うことです。 GCCではコンパイル時にこの三つの文字コードを指定できます。問題になっている2.の文字コードを日本語のPoweShellの文字コードであるCP932に指定するのが、`-fexec-charset=CP932`になります。 【補足】 * CP932はWindowsで使われるShfit_JISの亜種です。MS932やWindows-31Jという別名で言われることもあります。 * PowerShell側をUTF-8にするという方法もあります。`chcp 65001`がそのコマンドです。 * ソースコードがShift_JISでもコンパイルできることがありますが、壊れたUTF-8として扱っているだけに過ぎません。特に`'表'`のような2バイト目が`\`である文字があるとコンパイルエラーになったりします。 * C11/C++11から追加された`u8"..."`リテラルは上記の指定と関係無くUTF-8のリテラルになります。文字列リテラルを環境に依存せずにUTF-8に強制させたいときに便利です。 * `char *`そのものには文字コード情報という物が存在しない事に注意してください。