tagCANDY CGI VBレスキュー(花ちゃん) の Visual Basic 2010 用 掲示板(VB.NET 掲示板) [ツリー表示へ]   [Home]
一括表示(VB.NET VB2005)
タイトル文字コードを変換
記事No7439
投稿日: 2008/05/02(Fri) 19:14
投稿者ゆうき
ゆうきです。こんばんは。

文字コードを変換したいと思っています。
UnicodeからShift-JISです。
XMLから読み込んで、読み込んだテキストを表示すると、
文字化けしてしまいます。

コード
        Dim shiftjis As System.Text.Encoding = System.Text.Encoding.GetEncoding("Shift-JIS")
        Dim unicode As System.Text.Encoding = System.Text.Encoding.UTF8
        Dim ucBytes As Byte() = unicode.GetBytes(読み込んで表示するテキスト)
        Dim sjBytes As Byte() = System.Text.Encoding.Convert(unicode, shiftjis, ucBytes)

        Label1.Text = shiftjis.GetString(sjBytes)

このコードだとLabel1に文字化けした文字が表示されてしまいます。

やり方が悪いのでしょうか。

よろしくお願いします。

[ツリー表示へ]
タイトルRe: 文字コードを変換
記事No7440
投稿日: 2008/05/02(Fri) 21:43
投稿者魔界の仮面弁士
> UnicodeからShift-JISです。
一口に Unicode の文字集合と言っても、そのエンコーディングには複数ありますよ。

Unicode メール等で良く使われるエンコードは、主に UTF-8 ですし、
OLE/COM の文字列や、Win32 の 〜W 系 API などで利用されるのは、
UTF-16 の BOM 無しリトルエンディアン。その他 UTF-7、UTF-16BE、
UTF-32 など、幾つかの種類があります。使いたいのはどれですか?

> XMLから読み込んで、読み込んだテキストを表示すると、
XML の読み込みなら、System.Xml 名前空間のクラス(XmlDocument等)に
任せるべきかと。正しい文字コードを自動判定して読み込んでくれますよ。

> 文字化けしてしまいます。
どの文字が、どのように化けてしまうのでしょうか?

> コード
えぇと…?

元の「テキスト」は、既に「文字列(String)」として取得済みなのですよね。
であれば文字コード変換の出番は、もはや無さそうに思えるのですが…。
("読み込んで表示するテキスト" を、どのようにして取得していますか?)

そもそも、文字列として既にデコードされているものを、
わざわざ UTF-8 バイナリにエンコードしなおして、
そこからさらに、UTF-8 → Shift_JIS へとコーディング変換し、
そうして得られた Shift_JIS バイナリを文字列に再デコードして
いるようですが、それ自体、意味のある作業には見えません。

[ツリー表示へ]
タイトルRe^2: 文字コードを変換
記事No7442
投稿日: 2008/05/03(Sat) 10:46
投稿者ゆうき
ゆうきです。

魔界の仮面弁士さん回答ありがとうございます。

> Unicode メール等で良く使われるエンコードは、主に UTF-8 ですし、
> OLE/COM の文字列や、Win32 の 〜W 系 API などで利用されるのは、
> UTF-16 の BOM 無しリトルエンディアン。その他 UTF-7、UTF-16BE、
> UTF-32 など、幾つかの種類があります。使いたいのはどれですか?
実はよくわからないんです。
RSSを読み込むソフトを作っていて、RSSのXMLを書き出すのは
自分ではなく、別のソフトなので、どのエンコードで
書き出しているのかすらわからないのです。

> > XMLから読み込んで、読み込んだテキストを表示すると、
> XML の読み込みなら、System.Xml 名前空間のクラス(XmlDocument等)に
> 任せるべきかと。正しい文字コードを自動判定して読み込んでくれますよ。
外部(インターネットからダウンロードしたソースファイル)を使って
XMLを読み込んでいます。なので、XmlDocumentクラスは使えません。
そのソースファイルで読み込んでいるので何のエンコードで読み込んでいるか
もわかりません。

> > 文字化けしてしまいます。
> どの文字が、どのように化けてしまうのでしょうか?
E217・n・・・{・・・・E・・・・・・・@・X・V・H・・・I・・
209・n・・・l・・・k・・・E・・・・・・@・a・J・・
こんな感じです。
> 元の「テキスト」は、既に「文字列(String)」として取得済みなのですよね。
> であれば文字コード変換の出番は、もはや無さそうに思えるのですが…。
そうですか・・・
やはりやり方が間違っていたのですね。

> そもそも、文字列として既にデコードされているものを、
> わざわざ UTF-8 バイナリにエンコードしなおして、
> そこからさらに、UTF-8 → Shift_JIS へとコーディング変換し、
> そうして得られた Shift_JIS バイナリを文字列に再デコードして
> いるようですが、それ自体、意味のある作業には見えません。
では、どのようにすれば文字コードを変換できるのでしょうか。

わかりにくくてすみません。
よろしくお願いします。

[ツリー表示へ]
タイトルRe^3: 文字コードを変換
記事No7443
投稿日: 2008/05/03(Sat) 14:18
投稿者魔界の仮面弁士
> 実はよくわからないんです。
それは、調べ方が分からないという意味でしょうか?
それとも、調べていないから分からないという意味でしょうか?

状況を十分に理解しないままコーディングしていくと、化けたデータをさらに化けさせ、
取り返しがつかない状態にまで破損させてしまう事もありえますよ。

> RSSを読み込むソフトを作っていて、RSSのXMLを書き出すのは
RSS であれば尚のこと、System.Xml を使うべきかと思いますよ。

> 自分ではなく、別のソフトなので、どのエンコードで
> 書き出しているのかすらわからないのです。
事前に分からずとも、取得した時点では分かりますよね。
XML では、文字化けが発生せぬよう、明確な規則を持っているのですから。
http://www.atmarkit.co.jp/fxml/rensai/xmlwomanabou06/learning-xml06.html

XmlDocument.Load では、その規則を元に、正しい文字コードが判定され、
正しい文字列へとデコードされますので、ご自身で把握しておらずとも、
データを正確に読み込ませることができます。


> 外部(インターネットからダウンロードしたソースファイル)を使って
> XMLを読み込んでいます。なので、XmlDocumentクラスは使えません。
なぜ、XmlDocument クラスを使えないのでしょうか?
URL を指定して読み込むことも、XML データを文字列として読み込むことも、
ダウンロードしたファイルを指定することもできますけれども…。


> > > 文字化けしてしまいます。
> > どの文字が、どのように化けてしまうのでしょうか?
> (中略)
> こんな感じです。
えぇと、私が「どのように化けたか」を聞いたのではなく、
「どの文字が、どのように化けたか」を聞いていた事に注意してください。

String 自体には、文字コード情報は含まれていないので、どのような経路で
化けてしまったのかを知るために、変換前後の両方のデータをお聞きした次第です。


> では、どのようにすれば文字コードを変換できるのでしょうか。
そもそも文字コード変換というのは、文字化けしたデータを復元するために
あるのではありません。一度化けた物は、その時点でデータの一部が損傷している
可能性が高いため、元の正しいデータに戻せる保証はありません。

まずは、処理手順を見直してみてください。元となるデータが、文字化けしている
破損状態の String しか無いのであれば、文字コード変換の余地は
ほとんど残されていないものと思ってください。

本当に読み込ませるべきは、ダウンロードした生の XML ファイルそのもの、
すなわち、ファイルのパスや Byte() あるいは Stream といったデータであるべきです。



たとえば「あ」という文字の場合、そのバイナリは、それぞれ
 Shift_JIS なら、82 A0
 euc-jp なら、A4 A2
 UTF-16 なら、42 30 など
 UTF-8 なら、E3 81 82
となりますよね。

E3,81,82 というバイナリを、UTF-8 でデコードすると、「あ」になりますが、
E3,81,82 というバイナリを、Shift_JIS でデコードすると「縺?」になります。

このとき、Shift_JIS にとっての E3,81 というバイナリは「縺」に一致しますが、
Shift_JIS にとっての 82 は、全角文字の 1 バイト目というデータを意味し、
それ単独では文字となりえません。そのため、2 文字目は破損状態となります。

そして『UTF-8 → Shift_JIS への文字コード変換』を行うというのは、
「縺?」という String を、「あ」という String に変換する事ではなく(それは不可能)、
E3,81,82 というバイナリを、82,A0 というバイナリにする作業を意味する事に注意してください。
そしてこのような変換作業には、Encoding.Convert メソッドを利用できます。

[ツリー表示へ]
タイトルRe^4: 文字コードを変換
記事No7444
投稿日: 2008/05/04(Sun) 09:20
投稿者ゆうき
ゆうきです。おはようございます。

魔界の仮面弁士さん、回答ありがとうございます。
説明不足ですみません。

> > RSSを読み込むソフトを作っていて、RSSのXMLを書き出すのは
> RSS であれば尚のこと、System.Xml を使うべきかと思いますよ。
>
> > 自分ではなく、別のソフトなので、どのエンコードで
> > 書き出しているのかすらわからないのです。
> 事前に分からずとも、取得した時点では分かりますよね。
> XML では、文字化けが発生せぬよう、明確な規則を持っているのですから。
> http://www.atmarkit.co.jp/fxml/rensai/xmlwomanabou06/learning-xml06.html

> > 外部(インターネットからダウンロードしたソースファイル)を使って
> > XMLを読み込んでいます。なので、XmlDocumentクラスは使えません。
> なぜ、XmlDocument クラスを使えないのでしょうか?
> URL を指定して読み込むことも、XML データを文字列として読み込むことも、
> ダウンロードしたファイルを指定することもできますけれども…。
すみません、インターネットからダウンロードしたソースファイルというのは、
VB.NETのコードファイル(*.vb)のことで、XMLのことではありません。

外部(インターネットからダウンロードしたソースファイル)を見てみたところ、
XmlDocument.Loadメソッドを使っていました。
WebClientクラスでインターネットからRSS(XML)をダウンロードし
(OpenReadメソッド)、StreamReaderクラスでOpenReadメソッドで読み込んだ
ストリームを読み込み、それをXmlTextReaderクラスで読み込んでいるように見えます。

XMLのバージョンを見てみたところ、Version 1.0で、Encoding Shift-JISでした。
なので、Shift-JISからStringのUnicodeへの変換に失敗しているように見えるのですが、
魔界の仮面弁士さんの話だと、
> XmlDocument.Load では、その規則を元に、正しい文字コードが判定され、
> 正しい文字列へとデコードされますので、ご自身で把握しておらずとも、
> データを正確に読み込ませることができます。
ということなので、Shift-JISからUnicodeへの変換に失敗していることは
ないと思えるのですが。

本当に説明不足ですみません。
よろしくお願いします。

[ツリー表示へ]
タイトルRe^5: 文字コードを変換
記事No7447
投稿日: 2008/05/04(Sun) 16:39
投稿者YuO
> WebClientクラスでインターネットからRSS(XML)をダウンロードし
> (OpenReadメソッド)、StreamReaderクラスでOpenReadメソッドで読み込んだ
> ストリームを読み込み、それをXmlTextReaderクラスで読み込んでいるように見えます。

StreamReaderを経由しているのが間違いです。
StreamReaderの作成時点でエンコーディングがわかっている必要がありますから。

そもそも,WebClientなんぞつかわずとも,XmlDocument.Loadメソッド
http://msdn.microsoft.com/ja-jp/library/875kz807.aspx
でいきなりURLを指定できます。XmlTextReaderを使いたいとしても,Createメソッド
http://msdn.microsoft.com/ja-jp/library/w8k674bf.aspx
でやはりURLを指定出来ます。

そのため,WebClientを経由する必要自体がないです。

[ツリー表示へ]
タイトルRe^6: 文字コードを変換
記事No7448
投稿日: 2008/05/04(Sun) 17:57
投稿者ゆうき
ゆうきです。

YuOさん、回答ありがとうございます。

> StreamReaderを経由しているのが間違いです。
> StreamReaderの作成時点でエンコーディングがわかっている必要がありますから。
そうですよね。ダウンロードして手に入れたソースコードだったので
変更して動かなくなったら・・・と思うと不安で変更できずにいました。

> そもそも,WebClientなんぞつかわずとも,XmlDocument.Loadメソッド
> http://msdn.microsoft.com/ja-jp/library/875kz807.aspx
> でいきなりURLを指定できます。
そうですか。変更してみたいと思います。

ここからとったものを変えて作ろうと思っていました。
http://www.microsoft.com/japan/msdn/coding4fun/usingkits/practice/rssscr01.mspx

ありがとうございました。

[ツリー表示へ]