SHIFT_JISとWindows-31Jと、から〜(WAVE DASH)
今までわかったふりをしてきた文字コードの復習。
間違ってたらつっこんで下さい。
Eclipse上で以下のファイルを作成して実行します。
package sample; import java.nio.charset.Charset; public class Sample { public static void main(String[] args) { System.out.println(Charset.defaultCharset().name()); String kara = "〜"; System.out.printf("Unicode:%x%n", (int)kara.charAt(0)); System.out.println(kara); } }
まず実行結果を。
windows-31j Unicode:ff5e 〜
僕の環境だとこんなかんじで表示されます。
で、こっから。
まず、ソースコードSample.javaのテキストファイルエンコーディングを確認。
Eclipse上でソースファイルを選択してプロパティを表示します。
そーするとデフォルト設定のMS932になっていることが確認できます。
MS932=Windows-31Jと同じです。
また、実行結果からわかるように
VMのデフォルトのキャラクタセットもWindows-31Jになっています。
この結果としてEclipseのコンソール出力時もWindows-31Jで出力される、ということになります。
なのでこの場合、なんてことなく実行できます。
コンソール出力時にSHIFT_JISで出力してみると
EclipseからRun Configurationsを選択し、CommonタブからConsole EncodingをSHIFT_JISに変更します。
そんで実行すると、いい具合に文字化けします。
Shift_JIS Unicode:ff5e ?
なぜ文字化けするか?
「〜」(WAVE DASH)は、
Windows-31Jの場合とSHIFT_JISの場合とでUnicodeへのマッピングが違います。
文字 | SHIFT_JIS | Windows-31J |
〜(WAVE DASH) | U+301C | U+FF5E |
Sample.javaのテキストファイルエンコーディングはWindows-31Jでした。
また、さきほどの文字化けした例の実行結果を見ると、
Shift_JIS Unicode:ff5e ?
Unicode:ff5eとなっています。
つまり、これは
String kara = "〜";
のステートメントで、変数karaはUnicodeのU+ff5eという値を保持する、ということを意味します。
このU+ff5eのデータを、
System.out.println(kara);
としたとき、コンソール出力時のエンコードはSHIFT_JISであるため文字化けが発生します。
(SHIFT_JISで「〜」文字を出力するには、U+301Cでなければならない)
SHIFT_JIS出力時に「〜」文字を出力するには
U+ff5eをU+301Cに変換してあげればOK。
コードはこんなかんじ。ちょっと雑。
package sample; import java.nio.charset.Charset; public class Sample { public static void main(String[] args) { System.out.println(Charset.defaultCharset().name()); String kara = "〜"; System.out.printf("Unicode:%x%n", (int)kara.charAt(0)); // U+ff5eをU+301cに変換 if(0xff5e == (int)kara.charAt(0)){ kara = "\u301c"; } System.out.println(kara); } }