teratail header banner
teratail header banner
質問するログイン新規登録

回答編集履歴

6

元に戻すって何だ?

2019/11/03 14:24

投稿

raccy
raccy

スコア21768

answer CHANGED
@@ -37,11 +37,11 @@
37
37
 
38
38
  うまくコンパイル出来ましたね。実際に実行してみてください。おぉっと、文字化けしませんでしたね。ソースコードはShfit_JISで、環境はUTF-8のはずです。なのにうまくいきました。何故なんでしょうか?
39
39
 
40
- ここまでちゃんと読んでいればわかるはずです。ソースコードの文字コードとコンパイルによって出力されたバイナリに埋め込まれた文字コードは関係が無いと言うことです。それぞれ別々に管理されており、環境のデフォルトまたはコンパイラオプションによって決定されます。コンパイルの文字コードは、GCCであれば`-fexec-charset`で指定可能です。このオプションはそれぞれバラバラに設定でき、文字コードの変換が行われることになります。
40
+ ここまでちゃんと読んでいればわかるはずです。ソースコードの文字コードとコンパイルによって出力されたバイナリに埋め込まれた文字コードは関係が無いと言うことです。それぞれ別々に管理されており、環境のデフォルトまたはコンパイラオプションによって決定されます。コンパイルの文字コードは、GCCであれば`-fexec-charset`で指定可能です。このオプションはそれぞれバラバラに設定でき、文字コードの変換が行われることになります。
41
41
 
42
42
  さて、最初の文字化けの話に戻ります。文字化けしたのはShift_JISのコードをUTF-8として解釈したからでした。この処理では、UTF-8として解釈できる文字はそのまま、解釈できない文字は`�`REPLACEMENT CHARACTER(U+FFFD)に置き換えて、バイナリに埋め込みます(この置き換えはiconvの動作に依存したものと思われます)。そして実行される環境もUTF-8であるため、解釈できた一部の文字Tvと解釈できずに置き換わられ�が表示されるというわけです。
43
43
 
44
- す方法は次の二つです。
44
+ 文字化けしないようにす方法は次の二つです。
45
45
 
46
46
  1. ソースコードの文字コードをコンパイル時に指定する。
47
47
  2. 環境のデフォルトにソースコードの文字コードを合わせる。

5

リダイレクトだと誤解を与えそうなので

2019/11/03 14:24

投稿

raccy
raccy

スコア21768

answer CHANGED
@@ -32,7 +32,7 @@
32
32
  では、上のコードをコンパイル出来るようにオプションを加えてみましょう。次のような形で`-finput-charset=cp932`オプションを加えてみてください(sjisとかでもできそうな気がするのですが、手元の環境ではcp932以外だとうまくいきませんでした)。
33
33
 
34
34
  ```
35
- g++ -finput-charset=cp932 <<ソースコードファイル名>>
35
+ g++ -finput-charset=cp932 {{ソースコードファイル名}}
36
36
  ```
37
37
 
38
38
  うまくコンパイル出来ましたね。実際に実行してみてください。おぉっと、文字化けしませんでしたね。ソースコードはShfit_JISで、環境はUTF-8のはずです。なのにうまくいきました。何故なんでしょうか?

4

異ならない場合も変換しているっぽい

2019/11/03 14:21

投稿

raccy
raccy

スコア21768

answer CHANGED
@@ -37,7 +37,7 @@
37
37
 
38
38
  うまくコンパイル出来ましたね。実際に実行してみてください。おぉっと、文字化けしませんでしたね。ソースコードはShfit_JISで、環境はUTF-8のはずです。なのにうまくいきました。何故なんでしょうか?
39
39
 
40
- ここまでちゃんと読んでいればわかるはずです。ソースコードの文字コードとコンパイルによって出力されたバイナリに埋め込まれた文字コードは関係が無いと言うことです。それぞれ別々に管理されており、環境のデフォルトまたはコンパイラオプションによって決定されます。コンパイル語の文字コードは、GCCであれば`-fexec-charset`で指定可能です。このオプションはそれぞれバラバラに設定でき、もし異なる文字コードであれば、文字コードの変換が行われることになります。
40
+ ここまでちゃんと読んでいればわかるはずです。ソースコードの文字コードとコンパイルによって出力されたバイナリに埋め込まれた文字コードは関係が無いと言うことです。それぞれ別々に管理されており、環境のデフォルトまたはコンパイラオプションによって決定されます。コンパイル語の文字コードは、GCCであれば`-fexec-charset`で指定可能です。このオプションはそれぞれバラバラに設定でき、文字コードの変換が行われることになります。
41
41
 
42
42
  さて、最初の文字化けの話に戻ります。文字化けしたのはShift_JISのコードをUTF-8として解釈したからでした。この処理では、UTF-8として解釈できる文字はそのまま、解釈できない文字は`�`REPLACEMENT CHARACTER(U+FFFD)に置き換えて、バイナリに埋め込みます(この置き換えはiconvの動作に依存したものと思われます)。そして実行される環境もUTF-8であるため、解釈できた一部の文字Tvと解釈できずに置き換わられ�が表示されるというわけです。
43
43
 

3

サンプルはShift_JISで保存してね

2019/11/03 06:40

投稿

raccy
raccy

スコア21768

answer CHANGED
@@ -12,7 +12,7 @@
12
12
 
13
13
  話を戻しましょう。UbuntuではC++上の`"~"`という文字列リテラルはUTF-8である。UbuntuのターミナルもUTF-8である。であれば、文字化けするのはおかしいはずです。では何がいけなかったのか?それはソースコードの文字コードとコンパイラが認識する文字コードが一致していなかったからです。
14
14
 
15
- ちょっとだけ変えたしたのコードを同じようにコンパイルしようとしてみてください。
15
+ ちょっとだけ変えたのコードを同じようにShift_JISで保存してコンパイルしようとしてみてください。
16
16
 
17
17
  ```C++
18
18
  #include<iostream>

2

chcpをちょっと足す

2019/11/03 06:37

投稿

raccy
raccy

スコア21768

answer CHANGED
@@ -8,7 +8,7 @@
8
8
 
9
9
  環境のデフォルトはOSやロケール設定によって異なります。Windowsであれば、デフォルトはANSIと言われる現在のロケールに合わせたASCII互換な文字コードです。日本語ロケールの場合は **Windows-31J** というShift_JISの亜種(Shift_JISとは一部が異なる)であり、Windows内部では932というコードページが割り当てられています(そのため、CP932、MS932とも言われます)。最新のmacOSやLinuxではUTF-8になっています(日本語ロケール未設定の場合はen_US.UTF-8で、日本語ロケールにするとja_JP.UTF-8になるという形がほとんどです)。WSL上のUbuntuの場合はLinuxとして設定されるため、UTF-8がデフォルトになります。Windows側が日本語ロケールであれば、環境変数`LANG`が`ja_JP.UTF-8`になっている事でも確認できるはずです。
10
10
 
11
- おっとここで、先に進む前にターミナルの話をしなければなりません。ConEmuとかを使っていない場合、WSLのターミナル画面はコマンドプロンプトやPowerShellと同じWindowsのコンソール機能を使っています。このコンソール自体は複数の文字コードに対応しています。ウィンドウのバーを右クリックして「プロパティ」を開いてくみてください。「オプション」タグに「現在のコードページ」の所に現在のコードページ(Windowsで文字コードを識別するための番号)が表示されていることでしょう。日本語環境であれば、`932 (ANSI/OEM - 日本語 Shift-JIS)`か`65001 (UTF-8)`の何れかです。Windows標準のコマンドプロンプトやPowerShellは932になりますが、WSL上のUbuntuを立ち上げたときは自動的に65001に切り替わります。これは932なコマンドプロンプト上で`bash`とした場合も同様です。先程、WSL上のUbuntuはUTF-8になっていると言いましたが、このコンソール機能でもUTF-8となっているため、日本語のメッセージなどが文字化けせずに表示されるようになっています。
11
+ おっとここで、先に進む前にターミナルの話をしなければなりません。ConEmuとかを使っていない場合、WSLのターミナル画面はコマンドプロンプトやPowerShellと同じWindowsのコンソール機能を使っています。このコンソール自体は複数の文字コードに対応しています。ウィンドウのバーを右クリックして「プロパティ」を開いてくみてください。「オプション」タグに「現在のコードページ」の所に現在のコードページ(Windowsで文字コードを識別するための番号)が表示されていることでしょう。日本語環境であれば、`932 (ANSI/OEM - 日本語 Shift-JIS)`か`65001 (UTF-8)`の何れかです。Windows標準のコマンドプロンプトやPowerShellは932になります(chcpコマンドで切り替え可能)が、WSL上のUbuntuを立ち上げたときは自動的に65001に切り替わります。これは932なコマンドプロンプト上で`bash`とした場合も同様です。先程、WSL上のUbuntuはUTF-8になっていると言いましたが、このコンソール機能でもUTF-8となっているため、日本語のメッセージなどが文字化けせずに表示されるようになっています。
12
12
 
13
13
  話を戻しましょう。UbuntuではC++上の`"~"`という文字列リテラルはUTF-8である。UbuntuのターミナルもUTF-8である。であれば、文字化けするのはおかしいはずです。では何がいけなかったのか?それはソースコードの文字コードとコンパイラが認識する文字コードが一致していなかったからです。
14
14
 

1

ちょっとだけ変えた

2019/11/03 06:36

投稿

raccy
raccy

スコア21768

answer CHANGED
@@ -8,7 +8,7 @@
8
8
 
9
9
  環境のデフォルトはOSやロケール設定によって異なります。Windowsであれば、デフォルトはANSIと言われる現在のロケールに合わせたASCII互換な文字コードです。日本語ロケールの場合は **Windows-31J** というShift_JISの亜種(Shift_JISとは一部が異なる)であり、Windows内部では932というコードページが割り当てられています(そのため、CP932、MS932とも言われます)。最新のmacOSやLinuxではUTF-8になっています(日本語ロケール未設定の場合はen_US.UTF-8で、日本語ロケールにするとja_JP.UTF-8になるという形がほとんどです)。WSL上のUbuntuの場合はLinuxとして設定されるため、UTF-8がデフォルトになります。Windows側が日本語ロケールであれば、環境変数`LANG`が`ja_JP.UTF-8`になっている事でも確認できるはずです。
10
10
 
11
- おっとここで、先に進む前にターミナルの話をしなければなりません。ConEmuとかを使っていない場合、WSLのターミナル画面はコマンドプロンプトやPowerShellと同じコンソール機能を使っています。このコンソール自体は複数の文字コードに対応しています。ウィンドウのバーを右クリックして「プロパティ」を開いてくみてください。「オプション」タグに「現在のコードページ」の所に現在のコードページ(Windowsで文字コードを識別するための番号)が表示されていることでしょう。日本語環境であれば、`932 (ANSI/OEM - 日本語 Shift-JIS)`か`65001 (UTF-8)`の何れかです。Windows標準のコマンドプロンプトやPowerShellは932になりますが、WSL上のUbuntuを立ち上げたときは自動的に65001に切り替わります。これは932なコマンドプロンプト上で`bash`とした場合も同様です。先程、WSL上のUbuntuはUTF-8になっていると言いましたが、このコンソール機能でもUTF-8となっているため、日本語のメッセージなどが文字化けせずに表示されるようになっています。
11
+ おっとここで、先に進む前にターミナルの話をしなければなりません。ConEmuとかを使っていない場合、WSLのターミナル画面はコマンドプロンプトやPowerShellと同じWindowsのコンソール機能を使っています。このコンソール自体は複数の文字コードに対応しています。ウィンドウのバーを右クリックして「プロパティ」を開いてくみてください。「オプション」タグに「現在のコードページ」の所に現在のコードページ(Windowsで文字コードを識別するための番号)が表示されていることでしょう。日本語環境であれば、`932 (ANSI/OEM - 日本語 Shift-JIS)`か`65001 (UTF-8)`の何れかです。Windows標準のコマンドプロンプトやPowerShellは932になりますが、WSL上のUbuntuを立ち上げたときは自動的に65001に切り替わります。これは932なコマンドプロンプト上で`bash`とした場合も同様です。先程、WSL上のUbuntuはUTF-8になっていると言いましたが、このコンソール機能でもUTF-8となっているため、日本語のメッセージなどが文字化けせずに表示されるようになっています。
12
12
 
13
13
  話を戻しましょう。UbuntuではC++上の`"~"`という文字列リテラルはUTF-8である。UbuntuのターミナルもUTF-8である。であれば、文字化けするのはおかしいはずです。では何がいけなかったのか?それはソースコードの文字コードとコンパイラが認識する文字コードが一致していなかったからです。
14
14