質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
Java

Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

文字コード

文字コードとは、文字や記号をコンピュータ上で使用するために用いられるバイト表現を指します。

Q&A

解決済

2回答

18687閲覧

文字化けした文字を置換したい

kuroiyatujp

総合スコア7

Java

Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

文字コード

文字コードとは、文字や記号をコンピュータ上で使用するために用いられるバイト表現を指します。

0グッド

0クリップ

投稿2016/10/17 16:08

編集2016/10/18 16:05

###前提・実現したいこと
Java8にてSJISで保存されているCSVファイル読み込みメソッドを作成中です。
Unicodeに対応していない文字を読み込んだ場合その文字を半角スペースに置換したいと思っています。

###発生している問題・エラーメッセージ

Unicodeに未対応の文字を読み込んだ場合
未対応の文字は「?」として読み込まれました。
これを半角スペースに置換してしまうと元々「?」を入力していたものも
置換されてしまうため別の方法で置換したいと思っているのですが
方法を思いつくことができませんでした。

###試したこと

文字化けしてしまう文字を16進数にしてみたのですが
・CSVから読み込んだ文字化けを意味する「?」
・Stringで宣言した「?」
どちらも「3f」になってしまい判断することができませんでした。

※20161019補足
コードを調査をした結果としてお恥ずかしいのですが「試したこと」の作業内容に不備がありました。
SJIS形式で保存されるCSVファイルに「�」の文字を入力して保存。読み込みを行ったのですが、そもそも
この文字ではCSVファイルの時点で「?」に変換されていました。
そのため実際には「?」が入力されているCSVファイルを読み込み「?」を認識していただけであり、
試したことの内容としてふさわしくありませんでした。
誤った情報をお伝えしてしまい申し訳ありません。

説明に不備などありましたら申し訳ありません。
どうかご教授お願い致します。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

yuba

2016/10/17 17:19

SJISにあってUnicodeに対応する文字がない字? 外字とかNEC文字とかですか?
kuroiyatujp

2016/10/17 18:06

お恥ずかしながら具体的な文字の想定は抜けておりました。 SJISで保存されているCSVをJavaに取り込みたい → JavaはUnicodeで保持するらしい → じゃあ編集・出力するときに文字化けが残っていると嫌だから、Unicodeに対応していない文字をを半角スペースにしよう  という非常に単純な考え方で進めてしまっていたためです。補足として「試したこと」ではSJISで「81AD」に該当する「�」をCSVに入力し読み込むことで試していました。
ikedas

2016/10/17 21:56

実際にどんなコードを書いて試したのでしょうか。そこを教えてもらえないとアドバイスのしようがないかと。
kuroiyatujp

2016/10/18 16:07

補足させていただきました通り書いたコード自体に問題がありましたので、お見せするべきコードがなくなってしまっています。申し訳ありません。
guest

回答2

0

ベストアンサー

第3水準や第4水準を処理したいと言うことですね。

色々調べましたが、次のような事情のようです。

  1. 第3水準と第4水準もUnicodeにマッピングされており、対応するUnicodeは存在する。
  2. Shift_JIS <-> Unicode の変換のほとんどの実装において、第3水準と第4水準にほとんど対応していない。
  3. 第3水準と第4水準に対応していないフォントがある。(最新OSに入っている標準フォントであれば問題ない)

例に出されているShift_JISの81ADは(U+FF07)として登録されており、第3水準と第4水準に対応している変換であれば、正しく変換できるはずです。しかし、2.の事情はJavaにもあてはまっており、Java標準の機能(InputStreamやnew Stringで文字コードを指定するなど)で変換する場合は、割り当て無しとして代替文字に置き換えてしまいます。

そこで、対応する手段は二つです。

  1. 第3水準と第4水準に対応したShift_JIS->Unicode変換をするライブラリを探す。または、自分で作る。

マッピングはhttp://vagus.seesaa.net/article/31404091.html等を参考にしてください。正確性を求める場合はJISやUnicodeの規格書見る必要があるかも知れません。
2. 代替文字で我慢する。
質問で言っていた方法です。代替文字を任意の文字にするにはCharsetDecoderを使って、implOnUnmappableCharacterをオーバーライドする必要があると思います。

それで、2.の具体的なやりかたですが、ちょっと今、時間が無いので、誰も書かなかったら、後で追記します。

投稿2016/10/17 22:29

編集2016/10/17 22:31
raccy

総合スコア21735

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

ikedas

2016/10/18 00:42

念のため1.について。 「第3水準」「第4水準」というのJIS X 0213に新たに収録された漢字のことを言っておられるのかと思います。このJIS X 0213という文字集合をシフト符号化表現で符号化した「Shift_JISX0213」や「Shift_JIS-2004」は、現在一般に使われているいわゆる「シフトジス」(実際にこの質問で扱うのは、Shift_JISの文字集合にベンダ拡張を加えた「Microsoftコードページ932」) とは互換性がありません。 また、重箱の隅をつつくようですが、例示されたU+FF07の文字は厳密にはJIS X 0208やJIS X 0213に収録されてはいません (JIS X 0208のときから、過去との互換性にかかわる用途で使用することができることにはなっていました)。 ちなみに、いわゆるシフトジスのベンダ拡張部分を何と呼ぶかは悩ましいですが (かつては「機種依存文字」といいましたが、今では実情に合わない)、「半角片仮名、丸付き数字、ベンダ選定漢字など」と具体例を列挙する方法も考えられます。 2.については、いったんユニコードに変換し、U+FFFDを任意の文字に置換するという方法も考えられますね。
kuroiyatujp

2016/10/18 15:33

raccy 様 原因とその理由、また解決策まで明示的に示していただきありがとうございます。 解決策としては提示いただきました2.を使いたいと思いますが、想定が曖昧であったためその辺りを明確にした上で対応したいと思います。 ただ教えて頂きましたCharsetDecoderについては調べてみます!
kuroiyatujp

2016/10/18 15:36

ikedas 様 解説いただきありがとうございます。 互換性の問題など把握していないことばかりでとてもためになります。 改めて文字コードのことを勉強し直します。
guest

0

どちらも「3f」になってしまい判断することができませんでした。

raccyさんがおっしゃっているCharsetDecoderは文字変換を使う場所で内部的に使われていますが、Windowsであればデフォルトで文字セットとしてMS932用のものが選択されている(はず)です。さてCharsetDecoderのリファレンスを見ると変換不可能な文字は例外を起こしたり変換不可であったことを示す置換文字に変換されたりといろいろなふるまいをさせることが可能です。

デフォルトの動作では(たぶん)デフォルトの置換文字である'\uFFFD'に置換されているのだと思えます。この文字をMS932でMicrosoft ShiftJISに変換すると0x3Fすなわち'?'に変換されてしまうようですが、ShiftJISへ変換するまえ段階のUnicodeでなら'\uFFFD'なので'?'(Unicode='\u003F')と区別できると思います。変換した結果をファイルに出す前にJavaプログラム内で確認してみてはいかがですか?

回答がしりきれになってる感じだったので若干蛇足な補足を・・・

CSVから読み込んでJavaプログラム(Unicodeの世界)にいるうちに'\uFFFD'をほかの都合のよい文字に置き換えたら質問者さんのやりたいことは達成できると思います。一度'\uFFFD'をファイルへ吐き出す(その際にUnicode->MS932の変換が行われてしまう)と、もはや'?'と判別不能になるのですから。

ちなみにJavaが'\uFFFD'をデフォルトにしている理由はそこがUnicodeで未割当文字になっているからと思えます。

Unicode表 0xFFxx

この文字を'?'に変換しているのはMS932さんつまりMicrosoftの仕様になるのですが余計なことをしてくれるものだと思いました・・・ちょうど今自分もJIS X 0201/JIS X 0208の変換問題を考えていてMS932さんの落とし穴を知りつつあるところです。

投稿2016/10/18 05:18

編集2016/10/18 05:37
KSwordOfHaste

総合スコア18394

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

KSwordOfHaste

2016/10/18 05:41

「余計なことをしてくれるものだ」といっちゃいましたが、それはやろうとしていることに都合がわるいという単なるプログラマーのぼやきです。一般のユーザーにとってエディターの動作がおかしくなるような危険な文字にならないように配慮してあると考えるとこの変換は親切設計であるともいえましょう。立場が違えばということですね。
kuroiyatujp

2016/10/18 15:57

KSwordOfHaste様 ご回答ありがとうございます。 恥ずかしながら現在の自分ではわからない部分が多く、一度コードを書きいろいろ試してみたいと思います。申し訳ありません。 立場が違えばのお話もしっかり考えて実装に生かしていきたいと思います!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問