- PR -

文字化けについて

投稿者投稿内容
JW
常連さん
会議室デビュー日: 2004/01/14
投稿数: 49
投稿日時: 2004-04-16 21:28
引用:

どちらも、「屁」という漢字を一旦 JIS コード化したものを、16進で出す共通部分があるが、
何故か自作の Java では nkf + jhd で出したものに含まれる後半3バイト分がどこかへ
飛んでしまっている。しかし、デコードは成功しているようだ。



その3バイトは、「次の文字(以降)はASCIIが来る」なので、デコード自体は成功するでしょう。ISO-2022-JPの仕様には沿ってないようですが。

で、これはURLEncoder が駄目ですね。
(ISO-2022-JPでURLエンコード済みURLなんて意味あるのかどうか…?)


コード:
ByteArrayOutputStream stream = new ByteArrayOutputStream();
OutputStreamWriter writer = new OutputStreamWriter(stream, "ISO-2022-JP");
writer.write("漢字");
writer.flush();
//writer.close();           ←これ
byte[] by = stream.toByteArray();
for(int j=0; j<by.length; j++) {
     System.out.print(Integer.toHexString(by[j]) + " ");
}
System.out.println();


コメントでつぶしてあるclose() の有無で結果の違いを見てください。

closeするか本当に次にASCIIの文字がくれば「ESC '(' 'B'」の3バイトでASCIIに切り替えればいいのですが、closeしないとまだ入力があるかもしれない、(入力される可能性がある)次の文字も JIS X 0208の文字の可能性があるため ASCIIに切り替える事ができない、ってことが原因です。

URLでISO-2022-JP使う人なんてまずいないので問題にならなかったのかもしれません。
単にバイト列の確認したいだけなら上のコードで充分だし…
kirito
常連さん
会議室デビュー日: 2004/03/19
投稿数: 24
投稿日時: 2004-04-19 10:37
追伸です
str1 = str1.replace('\u2212', '−');
を試してみましたが直りません
これはDBから値を取り出す周辺に記述しないといけないのでしょうか
私は単に画面に出力する直前に書きました
コブラ
ぬし
会議室デビュー日: 2003/07/18
投稿数: 1038
お住まい・勤務地: 神奈川
投稿日時: 2004-04-19 11:33
>closeするか本当に次にASCIIの文字がくれば「ESC '(' 'B'」の3バイトでASCIIに切り替え
>ればいいのですが、closeしないとまだ入力があるかもしれない、(入力される可能性がある)
>次の文字も JIS X 0208の文字の可能性があるため ASCIIに切り替える事ができない、っ
>てことが原因です。

お詳しいっ!
いや、ここまで具体的に解説されるとは。
いま一つ疑問があるのですが、

アプレット化した encode.html では「屁」が問題無くエンコードされ、ただのコンソール出力
では「屁」だと byte列に変換してからの URLEncode 時にオーバーフローしてしまいます。
byte列変換せずに URLEncode すると、今度は先の問題、「いつASCIIに切り替えるかのタイミング」
で後尾3バイトが消失してしまう。
なぜ、System.out.println() と setText() ではここまで挙動が違うのでしょうか?

[ メッセージ編集済み 編集者: コブラ 編集日時 2004-04-19 11:33 ]
kirito
常連さん
会議室デビュー日: 2004/03/19
投稿数: 24
投稿日時: 2004-04-21 14:27
追伸です
str1 = str1.replace('\u2212', '−');
を試してみましたが直りません
str1 = str1.replace('a','\u2212');
を実行するとaの代わりに−が出てきます
これにより2つのことが分かります、@化けている文字のコードは\u2212ではない
A\u2212が化けることはない
環境はlinux(euc)、DBはoracleです
山本 裕介
ぬし
会議室デビュー日: 2003/05/22
投稿数: 2415
お住まい・勤務地: 恵比寿
投稿日時: 2004-04-21 14:37
皆さんが直球の回答をしないのはこの現象がかなり FAQ なので、もう少し kirito さんに調査して自己解決してもらいたいからだと思いますよ。
すでにたくさんのヒントがでていますのでもう一歩掘り下げて調べてみましょう。
佐々木
大ベテラン
会議室デビュー日: 2003/03/30
投稿数: 121
投稿日時: 2004-04-21 14:53
化けたStringを相手に何をやっても本質的な解決にはなりません。
REPLACEMENT CHARACTER(\uFFFD)への変換は多対一であり、不可逆です。
情報量が減っているので元には戻せません。
化けていないStringを手に入れる努力をしましょう。
kirito
常連さん
会議室デビュー日: 2004/03/19
投稿数: 24
投稿日時: 2004-04-21 18:26
ありがとうございます
ところでj2sdk1.4.2_03に変えてみたところ?ではなく!)に化けるようになりました
これは何故なのでしょうか?

[ メッセージ編集済み 編集者: kirito 編集日時 2004-04-21 18:50 ]
uk
ぬし
会議室デビュー日: 2003/05/20
投稿数: 1155
お住まい・勤務地: 東京都
投稿日時: 2004-04-21 18:54
変更前のJDKのバージョンが不明ですが、おそらく
http://java.sun.com/products/archive/j2se/1.4.1_07/ja/changes.html#Shift-JIS
このためではないかと。

スキルアップ/キャリアアップ(JOB@IT)