「お昼の放送」の思い出

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するには、どのように修正すればよろしいでしょうか?

よろしくお願いします。

「SJIS->UTF8->SJISコード変」の質問画像

A 回答 (4件)

> 「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());
}
のように書けます。
    • good
    • 2

こんにちは。



すいません、こちらでは。。。

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)

参考URL:http://oshiete.goo.ne.jp/qa/5909905.html
    • good
    • 0
この回答へのお礼

angel_Z 様

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

ただし下から2行目
reverseBytes = sjisEnc.GetBytes(TextBox1.Text)
は必要ないです。

要するに、偶数にしておかなければならないということなのですね。
奇数の場合は、空白がUTF8->SJISの場合、残っているようですので、
空白削除すれば、うまくいきそうです。

これで5歩前進しました。

お礼日時:2012/11/15 00:56

Encoding.Convertの第一引数と第二引数が逆ではありませんか。


第1引数は第3引数のエンコーディングを指定します。
http://msdn.microsoft.com/ja-jp/library/kdcak6ye …
つまり,
> 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は「取り扱えません」。
    • good
    • 0
この回答へのお礼

Yune-Kichi 様

ありがとうございました、引数確認していませんでした。

「UTF8の文字列」は取り扱えないこともわかりました。

勉強不足ですいません、SJISの文字列をUTF8文字列でファイル等に書き出すのならば、可能なのでしょうか?

お礼日時:2012/11/15 00:31

こんにちは。



これではどうでしょうか?

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))
    • good
    • 1
この回答へのお礼

angel_Z 様

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

サンプルの
TextBox4.Text=utfEnc.GetString(reverseBytes)の部分がUTF8の文字列と考えて良いのでしょうか?
また、TextBox4.Textは「変換前」とフォーム上に表示されますが、UTF8に変換してもなぜに表示されるのでしょうか?
なんだか、納得できないんですよね。

すいません、変な質問で。

お礼日時:2012/11/14 18:08

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!

このQ&Aを見た人はこんなQ&Aも見ています


おすすめ情報