- 締切済み
SJIS->UTF8->SJISコード変換について
Windows XPでVB.NET2010で文字コード変換のプログラムを下記のように作成しました。 Dim beforeStr As String = "変換前" Dim utfEnc = System.Text.Encoding.GetEncoding(65001) Dim sjisEnc = System.Text.Encoding.GetEncoding(932) Dim beforeBytes() As Byte = utfEnc.GetBytes(beforeStr) Dim afterBytes() As Byte = System.Text.Encoding.Convert(sjisEnc, utfEnc, beforeBytes) Dim afterStr As String = sjisEnc.GetString(afterBytes) TextBox3.Text = afterStr Dim reverseStr As String = afterStr Dim reverseBytes() As Byte = sjisEnc.GetBytes(reverseStr) Dim baseBytes() As Byte = System.Text.Encoding.Convert(utfEnc, sjisEnc, reverseBytes) TextBox4.Text = utfEnc.GetString(baseBytes) SJIS->UTF8に変換して、確認のためにUTF8->SJISに逆変換してみましたが、 「変換」までは正しいのですが、最後の「前」が文字化けしてしまします。 正しくSJIS-.UTF8->SJISするには、どのように修正すればよろしいでしょうか? よろしくお願いします。
- みんなの回答 (4)
- 専門家の回答
みんなの回答
- Yune-Kichi
- ベストアンサー率74% (465/626)
> 「UTF8の文字列」は取り扱えないこともわかりました。 うーん,下の引用文からはわかっていないように思えますが……。 > 勉強不足ですいません、SJISの文字列をUTF8文字列でファイル等に書き出すのならば、可能なのでしょうか? まず、根本。 「文字列はEncodingを持っていない」 これを理解して下さい。 Shift_JISだのUTF-8だのUTF-16だのというのは,「文字列とバイト列を変換するための規則」でしかありません。 Shift_JISのバイト列は存在しても,Shift_JISの文字列というものは,少なくとも.NET Frameworkの世界には存在しません。 ・特定のEncodingでの表現を保持したい場合はbyteの配列を使う ・Encodingが重要ではなく,文字列として扱いたい場合はstringを使う ・特定のEncodingでの表現と文字列の間の変換はEncodingクラスのGetBytesおよびGetStringメソッドを使う ・2つのEncoding間の表現の変換にはEncoding.Convertメソッドを使う ・ファイル等のStreamに関しては,StreamReaderやStreamWriterをラッパーとして使うことでStreamのEncodingでの表現と文字列の変換が可能 ちなみに,Shift_JISのファイルを読み込んでUTF-8のファイルとして出力する場合には, using (var reader = new StreamReader("input.txt", Encoding.GetEncoding("Shift_JIS"))) using (var writer = new StreamWriter("output.txt", Encoding.UTF8)) { writer.Write(reader.ReadToEnd()); } のように書けます。
- angel_Z
- ベストアンサー率66% (12/18)
こんにちは。 すいません、こちらでは。。。 Dim beforeStr As String = "変換前" 'こちらの部分は、もっと簡単な表現があるかもしれません。------ If (beforeStr.Length Mod 2) <> 0 Then beforeStr = beforeStr & " " '文字数が奇数の時は空白文字を付けたす End If '---------------------------------- Dim utfEnc = System.Text.Encoding.UTF8 Dim sjisEnc = System.Text.Encoding.GetEncoding(932) Dim afterBytes() As Byte = sjisEnc.GetBytes(beforeStr) Dim afterStr As String = sjisEnc.GetString(afterBytes) Dim reverseBytes() As Byte = utfEnc.GetBytes(afterStr) TextBox3.Text = sjisEnc.GetString(reverseBytes) reverseBytes = sjisEnc.GetBytes(TextBox1.Text) TextBox4.Text = utfEnc.GetString(reverseBytes)
- Yune-Kichi
- ベストアンサー率74% (465/626)
Encoding.Convertの第一引数と第二引数が逆ではありませんか。 第1引数は第3引数のエンコーディングを指定します。 http://msdn.microsoft.com/ja-jp/library/kdcak6ye(v=vs.100).aspx つまり, > Dim afterBytes() As Byte = System.Text.Encoding.Convert(sjisEnc, utfEnc, beforeBytes) は, Dim afterBytes = Encoding.Convert(utfEnc, sjisEnc, beforeBytes) です。beforeBytesはutfEnc.GetBytesで取得したデータですから。 また,Stringの内部表現は常に「UTF-16」です。 StringはEncoding情報を「持っていません」。 なので,「UTF8の文字列」という物を.NET FrameworkのStringは「取り扱えません」。
お礼
Yune-Kichi 様 ありがとうございました、引数確認していませんでした。 「UTF8の文字列」は取り扱えないこともわかりました。 勉強不足ですいません、SJISの文字列をUTF8文字列でファイル等に書き出すのならば、可能なのでしょうか?
- angel_Z
- ベストアンサー率66% (12/18)
こんにちは。 これではどうでしょうか? Dim beforeStr As String = "変換前" Dim utfEnc = System.Text.Encoding.UTF8 Dim sjisEnc = System.Text.Encoding.GetEncoding(932) Dim afterBytes() As Byte = sjisEnc.GetBytes(beforeStr) Dim afterStr As String = sjisEnc.GetString(afterBytes) Dim reverseBytes() As Byte = utfEnc.GetBytes(afterStr) TextBox4.Text = utfEnc.GetString(reverseBytes) 'ためしに反対も reverseBytes = sjisEnc.GetBytes(TextBox4.Text) MsgBox (sjisEnc.GetString(reverseBytes))
お礼
angel_Z 様 ありがとうございました。 できました。 サンプルの TextBox4.Text=utfEnc.GetString(reverseBytes)の部分がUTF8の文字列と考えて良いのでしょうか? また、TextBox4.Textは「変換前」とフォーム上に表示されますが、UTF8に変換してもなぜに表示されるのでしょうか? なんだか、納得できないんですよね。 すいません、変な質問で。
お礼
angel_Z 様 ありがとうございました。 できました。 ただし下から2行目 reverseBytes = sjisEnc.GetBytes(TextBox1.Text) は必要ないです。 要するに、偶数にしておかなければならないということなのですね。 奇数の場合は、空白がUTF8->SJISの場合、残っているようですので、 空白削除すれば、うまくいきそうです。 これで5歩前進しました。