none
文字コードの混在ですが RRS feed

  • 質問

  • いつもお世話になってます。
    XPのVB2008Exp環境でやっております。

    いつもながらの質問ですが

    あるデータ(文字データ)をバイト型で読み込んできました。
    そのデータは、Chr文字とSift-JISの混在です。
    すんなり読む方法ってどうしたら良いのでしょうか?

    また、今は区切って読み込んでいます。
    しかし、テキストボックスにつなげて表示したいのですがうまくいきません。
    なぜでしょうか?

    例:
       dim chrMOJI as string = char(byteA(54))
          dim Moji as string = System.Text.Encoding.GetEncoding(932).GetString(byteB)
         
          TextBox1.Text=chrMOJI & Moji

          これだと、chrMOJI・MOJIそれぞれは大丈夫ですが、TextBox1にはchrMOJIしか表示されません。

       dim chrMOJI as string = char(byteA(54))
          dim Moji as string = System.Text.Encoding.GetEncoding(932).GetString(byteB)
         
          TextBox1.Text=chrMOJI
       TextBox1.Text=TextBox1.Text & MOJI

          とやると表示されます。
       なぜなんでしょうか?

    お力お貸しください。
    2009年4月7日 8:22

回答

すべての返信

  • > そのデータは、Chr文字とSift-JISの混在です。

    「Chr文字」って何ですか? その他、byteA とか byteB なども定義が不明なようですが。
    2009年4月7日 13:37
  • > そのデータは、Chr文字とSift-JISの混在です。

    「Chr文字」って何ですか? その他、byteA とか byteB なども定義が不明なようですが。

    返信ありがとうございます。
    おかしな表現だったのでしょうか?

    まず、ファイル内容をバイト配列で読込ます。

    dim bs() as Byte
    ・・・読込は省略します。・・・・

    dim byteA as Byte
    dim byteB(11) as Byte

    byteA=bs(0)

    for i = 1 to 11
       byteB(i)=bs(i)
    next i

    dim chrMOJI as string = chr(byteA)
    dim Moji as string = System.Text.Encoding.GetEncoding(932).GetString(byteB)
         
    TextBox1.Text=chrMOJI & Moji

    こんな感じです。
    ブレイクで chrMOJI 及び Moji の値をみると ちゃんと入っていることが確認できましたが
    TextBox1に表示される結果は、 chrMOJIの値 のみ表示になります。

    一方

    TextBox1.Text=chrMOJI
    TextBox1.Text=TextBox1.Text & " " & Moji 

    とすると
    TextBox1に表示される結果は、 『chrMOJIの値 Mojiの値』 と表示されます。

    ご理解いただける書き方でしょうか?

    よろしくお願いいたします。
    2009年4月8日 11:46

  • dim chrMOJI as string = chr(byteA)
    dim Moji as string = System.Text.Encoding.GetEncoding(932).GetString(byteB)
         
    TextBox1.Text=chrMOJI & Moji

    こんな感じです。
    ブレイクで chrMOJI 及び Moji の値をみると ちゃんと入っていることが確認できましたが
    TextBox1に表示される結果は、 chrMOJIの値 のみ表示になります。
    再現させるためのコードを求められています。
    現状で足りない情報は、byteAの値が具体的にどんな数値が入っているかということと、byteBがどんな数値が入っているかということです。


    単純にchrMOJIやMojiにいわゆる普通の文字列("あいうえお"等)を入れて、&で繋げたら正しく動くはずです。
    そのbyteAやbyteBの中身によって、現象が起きたり、起きなかったりする可能性が高く、その情報が明らかにされない限り、的確なアドバイスは困難です。
    解決した場合は、参考になった返信に「回答としてマーク」のボタンを利用して、回答に設定しましょう(複数に設定できます)。
    2009年4月8日 14:08
    モデレータ
  • アップされたコードを見ると、半角全角、大文字小文字が正しく区別されてないようです。
    そのあたりの初歩的なことは大丈夫ですか?

    > 返信ありがとうございます。
    > おかしな表現だったのでしょうか?

    「Chr文字」というのは、1バイト(半角)のアルファベットや数字などの ASCII 文字のこ
    とを言っています? ASCII 文字のコードは Shift_JIS と同じです(文字コードが混在し
    ている訳ではない)。その点は理解されているでしょうか?

    > まず、ファイル内容をバイト配列で読込ます。

    ファイルの内容が、メモ帳で作った Shift_JIS コードのテキストファイルで、最初の文字が
    半角アルファベット/数字、2文字目以降が全角日本語のようですが、そうであれば以下のよ
    うにしても同じで、

    Dim unicodeString As String = "aあいうえおかきくけこ・・・・"
    Dim bs() As Byte = Encoding.GetEncoding("Shift_JIS").GetBytes(unicodeString)

    bs(0) には 'a' の ASCII コード(Shift_JIS と同じ)、bs(1) 以降には "あいうえおかきく
    けこ・・・・" の Shift_JIS コードが入ります。それを以下のようにすればTextBox1 には
    "aあいうえおか" と表示されるはずです。なお、For ループで byteB に bs を代入する部分
    が違いますので注意してください。

    Dim byteA As Byte
    Dim byteB(11) As Byte
    byteA = bs(0)
    For i = 0 To 11
        byteB(i) = bs(i + 1)
    Next i
    Dim chrMOJI As String = Chr(byteA)
    Dim Moji As String = System.Text.Encoding.GetEncoding(932).GetString(byteB)
    TextBox1.Text = chrMOJI & Moji

    2009年4月8日 15:18
  • SurferOnWwwさん
    返信ありがとうございます。

      >「Chr文字」というのは、1バイト(半角)のアルファベットや数字などの ASCII 文字のこ
      >とを言っています? 

    仰るとおりです。ASCII文字と言えば良かったのですね。
    ASCII文字と言って正しいのか不安があり「Chr文字」などと言ってしまいました。

      >ASCII 文字のコードは Shift_JIS と同じです(文字コードが混在し
      >ている訳ではない)。その点は理解されているでしょうか?

    どこかで見た覚えがあるので、自分もそう思っておりました。
    そのつもりで、ファイル内容を読み込み文字に変換しようと試みたわけなんですが
    読んだすべてが変換されずに半分だけが変換される状態で
    ASCII文字コードとShift_JISでは混在できないのかな?っと思ったわけです。


    SurferOnWwwさんの返信から
    自分の考え違いと思いファイルの内容をバイナリ表示するソフトを使って見てみました。

    すると
         54 49 2D 36 36 31 2E 50 56 00 20 20 20 20 20 20
        20 20 20 20 20 20 20 20 94 72 83 4B 83 58 20 81
         40 89 B7 93 78 20 20 20 20 20 20 20 20 20 20 20

    このような中身になっており
        54 49 2D 36 36 31 2E 50 56 の部分だけが変換されている事もわかりました。

    となると上記のあとの 00 が悪さの原因と思い 00 を外して変換したところ
    希望通りにいきました。

          00 これって NULLですよね?

    文字変換の際に影響を及ぼすものなのでしょうか?
    また怪しい表現になりますがNULLって「ない」を意味するだと思っています。
    確かに「なにに変換すれば?」と考えると「空白」?と思いますが、この理解は合ってますでしょうか?

    2009年4月10日 13:13
  • Azuleanさん
    返信ありがとうございます。

      >byteAやbyteBの中身によって、現象が起きたり、起きなかったりする可能性が高く、その情報が明らかにされない限り
      >的確なアドバイスは困難です。

    今回実感いたしました。
    以後、質問の仕方にも気をつけたいと思います。
    2009年4月10日 13:22
  • 00 これって NULLですよね?

    文字変換の際に影響を及ぼすものなのでしょうか?
    また怪しい表現になりますがNULLって「ない」を意味するだと思っています。
    確かに「なにに変換すれば?」と考えると「空白」?と思いますが、この理解は合ってますでしょうか?

    NULL ではなく NULL 文字です。そういう名前のれっきとした文字です。まあ一般的にはフォントを割り当てませんが。
    .NET では内部文字コードに UTF-16 を使用していますが、いわゆる NULL 文字は Unicode では U+0000 として文字に含まれていますし、.NET の Char/String でも Encoding 派生クラスでも正しく扱えます(Shift_JIS の 0x00 は 値 0 の Char 型オブジェクトになります)。
    ただ TextBox 等のコントロールでは、NULL 文字以降は表示できません(ご存知かもしれませんが、C/C++ などでは NULL 文字でもって文字列の終端とみなしていたためです。つまり NULL 文字以降を表示する必要がなかった)。表示させようと思ったら、String の Convert メソッド等で代替文字(一般的には空白ですね)に置き換える必要があります。
    ちなみに VB で NULL 文字を表現するのは ChrW(0) ですね。
    2009年4月10日 13:29
  • 以前、以下のスレッドで話題になったことがありますが、.NET でゼロがどのように表示
    されるかは未定義のようです。

    http://social.msdn.microsoft.com/Forums/ja-JP/vbgeneralja/thread/a08254fb-cf75-49a8-a0a9-99bd42315ff8

    コンソールアプリ、Windows アプリの TextBox、Web アプリの TexBox いずれも違っ
    て表示されます。

    そもそも、ゼロを表示しようとすることが間違っているようです。

    2009年4月10日 14:57