• 締切済み

バイナリファイルのデータから特定の番地のHEXデータを18バイトとって表示方法すると文字化けする。

現在、Visual C++ 2008 Express Editionでバイナリファイルを読み込んで、このファイルの0x1F65番地から18バイトを取得して、それをテキスト変換してテキストボックスに表示したいプログラムを作成しています。 バイナリデータをテキストデータに変換するプログラムを教えていただいて、それができたので、今度はもう少し長い18バイトを取得して、テキスト変換してテキストボックスに表示させようとしたのですが、バイナリデータとは違うデータが表示されるようになってしまいました。 どうしてこうなるのか原因がわからない状態です。 どなたか原因がわかるかたいらっしゃいませんでしょうか。どのように修正すれば良いかご教授お願いいたします。 private: System::Void button1_Click(System::Object^ sender, System::EventArgs^ e) { //指定したファイル名でStreamReaderを設定する try{ System::IO::StreamReader^ sr = gcnew System::IO::StreamReader("sample.bin"); //受け皿 array<wchar_t>^ buf=gcnew array<wchar_t>(18); //先頭から0x1f65バイト動かす sr->BaseStream->Seek(0x1f65,System::IO::SeekOrigin::Begin); //18バイト読み込む sr->Read(buf, 0, buf->Length); //此処でテキストボックスに入れる this->textBox1->Text= this->ToHEXString(buf); } catch(System::Exception^ ex){ System::Windows::Forms::MessageBox::Show(ex->ToString()); } //this->textBox1->Text = L"変更1"; this->textBox2->Text = L"変更2"; this->textBox3->Text = L"変更3"; }

みんなの回答

  • chie65535
  • ベストアンサー率43% (8525/19381)
回答No.4

System::IO::StreamReaderは「デフォルトの文字セットのテキストモード」でファイルを読み込みます。 ビルド時にプロジェクトの文字セットをUnicodeにしてあると、Unicodeがデフォルトの文字セットになります。 つまり「ファイルの中身を、Unicodeのテキストファイルだと思って」読み込むのです。 「Unicodeのテキストファイルだと思っている」のですから「Unicodeの文字コードに無い、変な文字」は、すべて、未定義の文字を意味する「REPLACEMENT CHARACTER」である「FFFD」に変換されてから読み込まれます。 つまり、F3とかEDとか9DとかD1とかFFなどの「Unicodeの文字コードに無い、変な文字は、すべてFFFDになってしまう」のです。 バイナリを読み込むなら、ストリームは一切のコード変換を行わないBinaryStreamを使わないとならないし、読み込むバッファもBYTE型の配列じゃないとならないです。 あと、バイナリファイルをテキストモードで開くと、改行コード(0A)が1つあるたびにSeekメソッドの位置が1つズレるので、読み込み開始位置も狂う筈です。

  • LunaSun
  • ベストアンサー率30% (4/13)
回答No.3

バイナリデータを扱うのだからストリームはBinaryStreamを使うべきですね。 後、wchar_tではなくBYTE(unsigned char)を使うのが良い。

参考URL:
http://msdn.microsoft.com/ja-jp/library/system.io.binaryreader(VS.80).aspx
  • Lchan0211
  • ベストアンサー率64% (239/371)
回答No.2

this->ToHEXString()の動作がおかしいのだと思いますが、 そのToHEXString()のコーディングが示されていないので それ以上コメントできません。 おそらくToHexStringの処理に誤りがあり、 0x80~0xffのデータを正しく処理できず、 FFFDと表示してしまったのだろうと思います。

maeken0012
質問者

お礼

回答いただきありがとうございました。ちょっと、私が質問した際に、のせ忘れていたコードがありましたので、ここで再度追加させてください。ちょっとまだわからないことで、現在0x1F6B番地のデータは0xF3とバイナリテキストエディタでは表示されているのですが、これをVC++でバイナリファイルを読み込んで、この番地の値をテキストボックスに表示させようとしたときに、なぜ”0xFFFD”という値になったのかがよくわかりません。この原因がわかりましたらご教授願います。 先ほど忘れていた関数”ToHEXString”のコードを追加させていただきます。 private: System::String^ ToHEXString(array<wchar_t>^% refArray){ //array<wchar_t>型バッファからHEXへの変換 System::String^ sHex = gcnew System::String(0, 0); int complete = 0; for each(wchar_t wc in refArray) { //HEX変換 sHex += System::String::Format("{0:X2}", int(wc)); //最後以外はカンマを付加する if(++complete < refArray->Length)sHex += ", "; } return sHex; }

  • S-Fuji
  • ベストアンサー率36% (592/1624)
回答No.1

実際のデータ内に、コントロールコードが含まれています。 これをそのまま表示しようとすると、おかしな表示になります。 ダンプ画像にも有りますが、テキスト文字コード以外は、「・」等を代用して表示するようにしましょう。

maeken0012
質問者

お礼

回答いただきありがとうございました。ちょっと、私が質問した際に、のせ忘れていたコードがありましたので、ここで再度追加させてください。ちょっとまだわからないことで、現在0x1F6B番地のデータは0xF3とバイナリテキストエディタでは表示されているのですが、これをVC++でバイナリファイルを読み込んで、この番地の値をテキストボックスに表示させようとしたときに、なぜ”0xFFFD”という値になったのかがよくわかりません。この原因がわかりましたらご教授願います。 先ほど忘れていた関数”ToHEXString”のコードを追加させていただきます。 private: System::String^ ToHEXString(array<wchar_t>^% refArray){ //array<wchar_t>型バッファからHEXへの変換 System::String^ sHex = gcnew System::String(0, 0); int complete = 0; for each(wchar_t wc in refArray) { //HEX変換 sHex += System::String::Format("{0:X2}", int(wc)); //最後以外はカンマを付加する if(++complete < refArray->Length)sHex += ", "; } return sHex; }

関連するQ&A

  • バイナリファイルのデータから特定の番地のHEXデータの表示方法

    現在、バイナリファイルのデータから特定の番地のデータだけをテキストボックスに表示させたいというプログラムを作成しております。 特定番地は0x1F65番地~の6バイトを抜き出し、そのHEXデータをテキストボックスにそのHEXがわかるテキストデータとして表示させたいと考えているのですが、この場合どのようにコーディングしたらよいのでしょうか。 現在のプログラムは private: System::Void button1_Click(System::Object^ sender, System::EventArgs^ e) { //指定したファイル名でStreamReaderを設定する try{ System::IO::StreamReader^ sr = gcnew System::IO::StreamReader("sample.bin"); //受け皿 array<wchar_t>^ buf=gcnew array<wchar_t>(6); //先頭から0x1f63バイト動かす sr->BaseStream->Seek(0x1f65,System::IO::SeekOrigin::Begin); //2バイト読み込む sr->Read(buf, 0, buf->Length); //此処でテキストボックスに入れる this->textBox1->Text= gcnew System::String(buf); } catch(System::Exception^ ex){ System::Windows::Forms::MessageBox::Show(ex->ToString()); } //this->textBox1->Text = L"変更1"; this->textBox2->Text = L"変更2"; this->textBox3->Text = L"変更3"; } コマンドボタンを押して、特定番地をBUFに入れた後テキストボックスに代入しています。これだとAsciiコードに準じたの文字が表示されてしまうので、そのHEX番号がわかるようにテキストボックスに入れたいとおもっています。 どうぞ、ご教授よろしくお願いいたします。

  • バイナリファイル読み込みプログラムのエラー内容

    現在、バイナリファイル読み込みプログラムを作成しており、だいぶエラーが減ってきたのですが、1つだけエラーが発生します。 作成したプログラム private: System::Void button1_Click(System::Object^ sender, System::EventArgs^ e) { //指定したファイル名でStreamReaderを設定する try{ System::IO::StreamReader^ sr = gcnew StreamReader(_T("sample.bin")); //受け皿 array<wchar_t>^ buf=gcnew array<wchar_t>(2); //先頭から0x1f63バイト動かす sr->BaseStream->Seek(0x1f63,System::IO::SeekOrigin::Begin); //2バイト読み込む sr->Read(buf, 0, buf->Length); //此処でテキストボックスに入れる this->textBox1->Text= gcnew System::String(buf); } catch(System::Exception^ ex){ System::Windows::Forms::MessageBox::Show(ex->ToString()); } //this->textBox1->Text = L"変更1"; this->textBox2->Text = L"変更2"; this->textBox3->Text = L"変更3"; } エラー内容は、 1>コンパイルしています... 1>RungeKutta.cpp 1>c:\mywork\felicareader_test\rungekutta\rungekutta\Form1.h(135) : error C2061: 構文エラー : 識別子 'StreamReader' 1>ビルドログは "file://c:\mywork\felicareader_test\RungeKutta\RungeKutta\Debug\BuildLog.htm" に保存されました。 1>RungeKutta - エラー 1、警告 0 ========== ビルド: 0 正常終了、1 失敗、0 更新不要、0 スキップ ========== 先ほどの”System::IO::StreamReader^ sr = gcnew StreamReader(_T("sample.bin")); ”文でエラーが発生しているようです。ちょっとエラー内容がわかりません。 ご存じである方いらっしゃいましたらどうぞご教授いただきますようよろしくお願いいたします。 ちなみにこのプログラムは、 コマンドボタンを押すと”sample.bin”ファイルを読み込んで、特定の番地の2バイトだけをテキストボックスに表示するというプログラムです。

  • Visual C++ 2008 Express Editionでバイナリファイルの読み込み方法

    いま、Visual C++ 2008 Express Editionで、コマンドボタンをクリックした時に、600kバイト程度のバイナリファイルから特定の番地のデータを抜き出して(2バイト分)、そのデータをテキストデータに変換してテキストボックスに表示させたいのですが、コードを作成したのですが、エラーがたくさんでて書き方がよくわかりません。 一応コマンドボタンのところはこのように書きました。まだ、ファイルを読み込むまで行っていません。 private: System::Void button1_Click(System::Object^ sender, System::EventArgs^ e) {    //指定したファイル名でStreamReaderを設定する    try{       sreader1=gcnew StreamReader("sample.txt");    }catch(Exception^ ex){       //Console::WriteLine(ex->Message);       return 0;   } this->textBox1->Text = L"変更1";    this->textBox2->Text = L"変更2"; this->textBox3->Text = L"変更3"; } }; どうかご教授いただきますようよろしくお願い致します。

  • ”System::IO::StreamReader”ってどういう意味ですか?

    Visual C++ 2008 Express Editionで、現在、600kバイト程度のバイナリファイルを読み込んで特定の番地のデータだけを取り出してそれをテキスト変換してテキストボックス内に表示させるというプログラムを作成しているのですが、このことをOKwaveでどのようにコーディングするかを教えてもらったところ、 System::IO::StreamReader^ sr=gcnew StreamReader(_T("sample.txt")); このような文を教えてもらったのですが、全く知識がなく何をやっているのかわかりません。 ”sr”というのは変数で、sample.txtからstreamReader関数でsample.txt内のデータをsr変数に 入れているという感じがしますが、”System::IO::StreamReader”とか”gcnew”とかの意味がよくわかりません。 どうかご教授お願いいたします。

  • C#におけるファイル読み取りの文字化け

    開発初心者です。 //Shift-JISコードとして開く System.IO.StreamReader sr = new System.IO.StreamReader(@txtShiteiFile.Text, System.Text.Encoding.GetEncoding(932)); //内容を全て読み込む string textAll = sr.ReadToEnd(); 以上の関数を使ってテキストファイル上の文字を読み取りしているのですが、 textAll 変数に入ったときに文字化けしています。 また、テキストファイルによっては文字化けしないときもあります。 この場合、どのような対処をすればよいのでしょうか?

  • VC++2005 StreamReader

    以前、ここでテキストボックスに保存してあるテキストファイルの表示方法を教えていただきました。 そのときの回答では、読み込みたいファイル名をまずテキストボックスに入れてStreamReaderを使って他のテキストボックスに表示するというプログラムを教えていただきました。 そこで今回質問したいことは、最初にファイル名をテキストボックスに入れずにファイルを表示するのはどうすればよいのかということです。 以下に現在使っているプログラムを書きます。 よろしくお願いします。 textBox1->Text = "p12.txt"; ←この部分について StreamReader^ streamReader = gcnew StreamReader(textBox1->Text); textBox2->Text = streamReader->ReadToEnd();

  • VB TEXTデータについて

    下記のコードでTEXTを読み取りできましたが、読み取ったデータを使用して座標計算したいのですが 例えば、6列6行あるとします、1列目(X)、2列目(y)、3列目(X1)、4列目(y2)、5列目(角度)、6列目(予備)、となっているものが6行あります、1列目・1行の値から、6列目・6行の値まで指定するとき どのようなコードがあるのでしょうか、宜しくお願いします。 Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click Dim sr As System.IO.StreamReader = Nothing ' Try Dim file As String = TextBox1.Text 'SRとは New System.IO.StreamReaderの略 sr = New System.IO.StreamReader(file, System.Text.Encoding.GetEncoding("shift_jis")) Dim doc As String = "" '1行ずつテキストを読み取る Do Until sr.EndOfStream '改行コードが取り除かれてしまうのでVBnewlineで改行を付け直し doc &= sr.ReadLine & vbNewLine Loop 'TEXTBOX.2にdocを代入 TextBox2.Text = doc Catch ex As Exception MessageBox.Show(ex.Message, "read") Finally If sr IsNot Nothing Then sr.Close() sr.Dispose() End If End Try End Sub

  • テキストファイルのデータからバイナリを作りたい

    現在、テキストデータとしてCSVファイル1つあたり8バイトのデータが1000個ほどのデータが書かれているファイルがあります。このデータをバイナリファイルへ数値も変換して行きたいと思っています。 たとえば1個目のデータ”12345678”というテキストデータをバイナリの"12345678"に変換したらそれを0x00番地に並べて、そして2個目のデータ”87654321”というデータをバイナリにしたらそれを0x90離れた場所に置いていき、それを1000回繰り返して、結果をバイナリファイルで出力したいのですが、何か簡単にできるフリーソフトなどありませんでしょうか? また、プログラムとかでも簡単にできるのならそうしたいのですが、どうしたらよいか教えていただけないでしょうか?

  • VB2008 バイナリデータの書き込みで

    現在、VB2008でバイナリデータを書き込むプログラムを作成しているのですが、String型のデータをバイナリデータに書き込むと、なぜかそのバイナリデータの先頭に05が入ってしまいます。 コードは以下のように記述しています。 TextBox1.Text = "TEST" Dim Bin As New System.IO.BinaryWriter(New System.IO.FileStream(filename, IO.FileMode.Create)) ~~~省略~~~ Bin.Write(TextBox1.Text) ~~~省略~~~ Bin.Close() 書き込まれたバイナリデータは、 05 54 45 53 54 で、テキスト欄では、 .TEST と表示されます。 分かりにくい質問で申し訳ありませんが、回答よろしくお願いします。

  • VB2008

    VB初心者です、よろしくお願いいたします。 現在、VB2008を使い、顧客名簿を作成しています。 前回の質問で、テキストファイルのファイル名だけを取得する方法は分かったのですが、そのファイルの内容をテキストボックスに表示する方法がうまくいきません。 ファイルの内容は 1行目→名前 2行目→メールアドレス 3行目→郵便番号 4行目→住所 5行目→購入した商品 をそれぞれ、textbox1~5に表示させたいと思っています。 書籍などで調べた結果 Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click Dim totalcount As Integer Dim oneline As String Dim sr As System.IO.StreamReader sr = New System.IO.StreamReader("C:hogehoge\" & ComboBox1.Text & ".txt") oneline = sr.ReadLine() sr.Close() Dim skipline As Integer Dim r As Random = New Random() skipline = r.Next(totalcount) sr = New System.IO.StreamReader("C:hogehoge\" & ComboBox1.Text & ".txt") Dim i As Integer = 0 Do While i < skipline sr.ReadLine() i += 1 Loop oneline = sr.ReadLine() sr.Close() TextBox1.Text = oneline TextBox2.Text = (skipline + 1).ToString() End Sub このような記述になりました。 textbox1には問題なく名前が表示されますが、textbox2には"1"と表示されてしまいます。 すみませんが、修正箇所を教えていただけませんか? よろしくお願いいたします。