JavaA2Z

KAB-studio > プログラミング > JavaA2Z > 文字化けとは

文字化け

日本語 文字化け
英語 transformed character
ふりがな もじばけ
フリガナ モジバケ

解説

出力された文字が正しくないこと。
単に「文字が違う」のではなく、たとえば「あ」が「縺」や「?」になっていたりと、全く違う文字になっており、読めない状態になっていることを「文字化けしている」と表現する。
 
文字化けは、主に2種類の要因によって発生する。
1つは、インターネット等の転送時に途中のデータが消えてしまった場合。Unicodeのように「数バイトで1文字を表現する」文字コードの場合には、途中の1バイトが消えるとそのあとのバイトが全てずれてしまい、全く読めなくなる。
もうひとつは、文字コードの変換時に正しくない文字コードを指定することである。文字コードは基本的に「自動検出」が難しく、自動検出で誤った文字コードと判断されてしまったり、手動設定時に正しくない文字コードを指定していた場合、さらに文字コードを指定できない場合等に発生する。
前者は偶発的に発生するが、後者はバグの一種であり、直さなければならない。
 
Webアプリケーションの場合、文字化けは入力時にも出力時にも発生しうる。また、入力時にも出力時にも、プログラムが複数組み合わされている場合にはそれぞれで文字コードの変換が必要となる可能性があり、それぞれを正しく設定しなければならない。そのため、Webアプリケーションでは頭の痛い問題である。
 
文字化けは「出力時の見た目」についての話で、本当に「変な文字に変換された」とは限らない。
たとえば「あ」が「?」として出力されていたとしても、それは出力できないから「?」という文字0x003F)が代わりに出力されただけで、出力しようとした文字列が「?」という文字というわけではない、かもしれないということである。
これを確かめるため、Stringクラスから「そのままデータとして取り出し出力する」必要がある。そうして出力された内容を「ダンプ」と言い、これを見て、なんの文字コードとして格納されたかを調べるためのヒントにする。
 
文字化けは、見た目がまったくわけわからず、しかも原因が非常に特定しにくいため、パニックになりやすい。
とりあえず冷静になり、ダンプを使って客観的に判断し、原因を少しずつ絞り込んでいくことが、解決への糸口となるだろう。

参考サイト

  • (参考サイトはありません)

(KAB-studioからのおしらせです)

サンプルプログラム(とか)サンプルを別ウィンドウで表示サンプルをクリップボードへコピー(WindowsでIEの場合のみ)

// Sample.java
import java.io.UnsupportedEncodingException;

// Sample.java
public class Sample
{
    public static void main( String[] args )
    {
        try
        {
            // たとえば文字コード「シフトJIS」での「あいう」を……
            byte[] source = new byte[] { (byte)0x82, (byte)0xA0, (byte)0x82, (byte)0xA2, (byte)0x82, (byte)0xA4 };
            // Unicodeに変換せずにセットされてしまうと……
            String string = new String( source, "ISO-8859-1" );
            System.out.println( string );
            // ???¢??
            // 文字化けします。

            // ただし、ここで出力されている「?」が、実際にstring変数の中に
            // 格納されているわけではありません。
            // 格納されている文字列を、println()メソッドが出力しようとして
            // できなかったから代わりに「?」を出力しているだけです。
            // そのため、デバッグする場合には、この中に入っている実際の文字列を
            // 取得する必要があります。

            // その場合、「16進ダンプ」を出力します。
            // 16進数形式で「中身をそのまま出力する」ことで、中に何が入っているのか
            // 調べます。
            char[] chars = string.toCharArray();
            forint iF1 = 0; iF1 < chars.length; ++iF1 )
            {
                System.out.println( Integer.toHexString( chars[iF1] ) );
            }
            // 82
            // a0
            // 82
            // a2
            // 82
            // a4

            // この結果が、sourceの各要素と同じだということを確認してください。
            // 慣れてくれば、この値から「シフトJISの『あいう』が入っている」
            // ということが直感で分かったりもします。

            // 文字化けしてる文字列は、StringクラスのgetBytes()メソッドの
            // の引数に"ISO-8859-1"を渡してbyte型配列として取りだしたあと、
            // 正しい文字コードで渡し直します。
            byte[] bytes = string.getBytes( "ISO-8859-1" );
            string = new String( bytes, "Shift_JIS" );
            System.out.println( string );
            // あいう

            // ただし、これができるのは、
            // String string = new String( source, "ISO-8859-1" );
            // の箇所で"ISO-8859-1"を指定することで「全く変換せずにセットしている」
            // ためです。
            // もしこの時になんらかの文字コードを指定してしまっていると、
            // 無理矢理変換してデータが壊れてしまうため、もう元には
            // 戻りません。
        }
        catch( UnsupportedEncodingException e )
        {
            // StringクラスのコンストラクタがUnsupportedEncodingException例外を
            // 投げるので拾います。第2引数で渡された文字コード
            // (上記の例では「ISO-8859-1」や「Shift_JIS)が、Javaではサポート
            // されていない文字コードの場合にエラーとなります。
            e.printStackTrace();
        }
    }
}
// Sample.java
import java.io.UnsupportedEncodingException;

// Sample.java
public class Sample
{
    public static void main( String[] args )
    {
        try
        {
            // たとえば文字コード「シフトJIS」での「あいう」を……
            byte[] source = new byte[] { (byte)0x82, (byte)0xA0, (byte)0x82, (byte)0xA2, (byte)0x82, (byte)0xA4 };
            // Unicodeに変換せずにセットされてしまうと……
            String string = new String( source, "ISO-8859-1" );
            System.out.println( string );
            // ???¢??
            // 文字化けします。

            // ただし、ここで出力されている「?」が、実際にstring変数の中に
            // 格納されているわけではありません。
            // 格納されている文字列を、println()メソッドが出力しようとして
            // できなかったから代わりに「?」を出力しているだけです。
            // そのため、デバッグする場合には、この中に入っている実際の文字列を
            // 取得する必要があります。

            // その場合、「16進ダンプ」を出力します。
            // 16進数形式で「中身をそのまま出力する」ことで、中に何が入っているのか
            // 調べます。
            char[] chars = string.toCharArray();
            for( int iF1 = 0; iF1 < chars.length; ++iF1 )
            {
                System.out.println( Integer.toHexString( chars[iF1] ) );
            }
            // 82
            // a0
            // 82
            // a2
            // 82
            // a4

            // この結果が、sourceの各要素と同じだということを確認してください。
            // 慣れてくれば、この値から「シフトJISの『あいう』が入っている」
            // ということが直感で分かったりもします。

            // 文字化けしてる文字列は、StringクラスのgetBytes()メソッドの
            // の引数に"ISO-8859-1"を渡してbyte型配列として取りだしたあと、
            // 正しい文字コードで渡し直します。
            byte[] bytes = string.getBytes( "ISO-8859-1" );
            string = new String( bytes, "Shift_JIS" );
            System.out.println( string );
            // あいう

            // ただし、これができるのは、
            // String string = new String( source, "ISO-8859-1" );
            // の箇所で"ISO-8859-1"を指定することで「全く変換せずにセットしている」
            // ためです。
            // もしこの時になんらかの文字コードを指定してしまっていると、
            // 無理矢理変換してデータが壊れてしまうため、もう元には
            // 戻りません。
        }
        catch( UnsupportedEncodingException e )
        {
            // StringクラスのコンストラクタがUnsupportedEncodingException例外を
            // 投げるので拾います。第2引数で渡された文字コード
            // (上記の例では「ISO-8859-1」や「Shift_JIS)が、Javaではサポート
            // されていない文字コードの場合にエラーとなります。
            e.printStackTrace();
        }
    }
}

この単語を含むページ

「みだし」に含まれているページ

「サンプルプログラムとか」に含まれているページ

はてなブックマーク 詳細を表示 はてなブックマーク ブックマーク数
livedoorクリップ 詳細を表示 livedoorクリップ ブックマーク数
Yahoo!ブックマーク 詳細を表示 users
del.icio.us 登録する RSSに登録
サンプルを別ウィンドウで表示
サンプルをクリップボードへコピー(WindowsでIEの場合のみ)
update:2005/08/16
このページは、Javaプログラミング言語についての用語を網羅した辞書「JavaA2Z」の一ページです。
詳しくは「JavaA2Z」表紙の説明をご覧ください。