こんにちはゲストさん。会員登録(無料)して質問・回答してみよう!

締切り済みの質問

バイナリファイルのデータから特定の番地の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";
}

投稿日時 - 2009-06-08 15:13:28

QNo.5027014

すぐに回答ほしいです

このQ&Aは役に立ちましたか?

0人が「このQ&Aが役に立った」と投票しています

回答(4)

ANo.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つズレるので、読み込み開始位置も狂う筈です。

投稿日時 - 2009-06-09 12:09:40

ANo.3

バイナリデータを扱うのだからストリームはBinaryStreamを使うべきですね。

後、wchar_tではなくBYTE(unsigned char)を使うのが良い。

参考URL:http://msdn.microsoft.com/ja-jp/library/system.io.binaryreader(VS.80).aspx

投稿日時 - 2009-06-08 19:26:20

ANo.2

this->ToHEXString()の動作がおかしいのだと思いますが、
そのToHEXString()のコーディングが示されていないので
それ以上コメントできません。

おそらくToHexStringの処理に誤りがあり、
0x80~0xffのデータを正しく処理できず、
FFFDと表示してしまったのだろうと思います。

投稿日時 - 2009-06-08 18:55:11

お礼

回答いただきありがとうございました。ちょっと、私が質問した際に、のせ忘れていたコードがありましたので、ここで再度追加させてください。ちょっとまだわからないことで、現在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;
}

投稿日時 - 2009-06-09 21:12:27

ANo.1

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

投稿日時 - 2009-06-08 15:21:12

お礼

回答いただきありがとうございました。ちょっと、私が質問した際に、のせ忘れていたコードがありましたので、ここで再度追加させてください。ちょっとまだわからないことで、現在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;
}

投稿日時 - 2009-06-08 19:41:29

あなたにオススメの質問