unsigned char型データの出力

解決


hoge  2006-04-30 08:21:55  No: 61563

NETプログラミングは初学です、よろしくお願いいたします
環境はVisual Studio 2005 VC8です、バイナリファイルを開いて、読込みテキストボックスへ表示したいのですが
unsigned char型のデータをテキストボックスに表示する方法を御教授お願いします
以下ソースです。
private: System::Void toolStripButton1_Click(System::Object^  sender, System::EventArgs^  e) {
                using ::System::Windows::Forms::DialogResult; 
                Stream^ fs;
                OpenFileDialog^ openFileDialog1 = gcnew OpenFileDialog;
                openFileDialog1->InitialDirectory = "D:\\hoge";
                openFileDialog1->Filter = "All files (*.*)|*.*";
                openFileDialog1->FilterIndex = 2;
                openFileDialog1->RestoreDirectory = true;
                if ( openFileDialog1->ShowDialog() == ::DialogResult::OK )
                        {
                                if ( (fs = openFileDialog1->OpenFile()) != nullptr )
                                        { 
                                        System::IO::BinaryReader ^ binReader = gcnew BinaryReader(fs);
                                        unsigned char c;
                                        while(binReader->PeekChar() != -1)
                                        {
                                                c = binReader->ReadByte();
                                                ここの書き方が分かりません?
                                                textBox1->Text = ここの書き方が分かりません?;
                                        }
                                        binReader->Close();
                                        } 

                        }
                }


Blue  2006-04-30 08:26:10  No: 61564

> unsigned char型のデータをテキストボックスに表示する方法
どのように表示させるのでしょうか?

10進数の数値?16進真数の数値?それともShift_JISとしての文字?

不明確なので良くわかりません。


hoge  2006-04-30 08:34:22  No: 61565

よろしくお願いしますBlueさん
16進数のデータとして出力したいのですが


Blue  2006-04-30 08:38:08  No: 61566

半角空白区切りに追加していく場合
StringクラスのFormatメソッドを使う方法。

textBox1->Text += System::String::Format("{0:X} ", c);


Blue  2006-04-30 08:42:15  No: 61567

ちなみに

2桁の時は {0:X2} 
英字を小文字にしたいときは {0:x}

にしてください。

MSDN:標準の数値書式指定文字列
http://msdn2.microsoft.com/ja-jp/library/dwhawy9k.aspx


Blue  2006-04-30 08:46:13  No: 61568

てか、ToStringで指定できました。

textBox1->Text += c.ToString("X2") + " ";


hoge  2006-04-30 09:07:20  No: 61569

Blueさん、無事解決していただきまして、ありがとうございます
最後に一点質問させてください、
unsigned char c;
のデータを配列もしくはポインタで受けたいのですが
textBox1->Text += System::String::Format("{0:X} ", c[0]);
としてみたところ、
error C2109: 配列または、ポインタでない変数に添字が使われました。
となりました、
cはchar型のデータなので、てっきり自動的に1バイトづつ、
配列に格納されているものと期待していたのですが勘違いだったようです
配列に受取り表示させる場合の方法を御教授願えませんでしょうか。


Blue  2006-04-30 09:52:15  No: 61570

質問の意図が良くわかりません。

> cはchar型のデータなので、てっきり自動的に1バイトづつ、
であっているはずです。

> c = binReader->ReadByte();
ここで、1バイト読み込んでいるんですから。
1バイトずつよんでぐるぐる回るコードですよね?(whileのところ)

配列で一気に読み込みたいならば、ReadBytesメソッドですけど。
http://msdn.microsoft.com/library/ja/default.asp?url=/library/ja/cpref/html/frlrfsystemiobinaryreaderclassreadbytestopic.asp


Blue  2006-04-30 09:58:27  No: 61571

> であっているはずです。
は違ってました。

> cはchar型のデータなので、てっきり自動的に1バイトづつ、
> 配列に格納されているものと
配列に格納されているコードは書かれていませんよね?
というか
unsigned char c;
は配列ではないですよね?(それはC言語でもそうですよね?)

// ファイルの終わりまで
while(binReader->PeekChar() != -1)
{
    // 1バイトファイルから読み込む
    c = binReader->ReadByte();
    // テキストに1バイト分の16進表記文字列を追加
    textBox1->Text += c.ToString("X2") + " ";
}


hoge  2006-04-30 10:33:49  No: 61572

失礼しました、文字表示が巧くできなかったので
表示させることばかり考えていて先走った質問をしてしまいました
テキストボックスへの16進表示と、後でデータの加工を行うのに
配列がどうしても不可欠なのです申し訳ございません
自分なりに考えて下記の様に書き直しましたが、コンパイルも通るのですが
実行すると
例外  不明なソフトウエアー例外(0xc0000409)がアップリケーション0x7a0922fcで発生しましたとなってしまいます。
本当はunsigned char c[11];の部分をmemset関数のような命令でファイルサイズ分だけ
確保したかったのですが、NETでの命令が分からないのでとりあえずc[11]としました。

        private: System::Void toolStripButton1_Click(System::Object^  sender, System::EventArgs^  e) {
                using ::System::Windows::Forms::DialogResult; 
                Stream^ fs;
                OpenFileDialog^ openFileDialog1 = gcnew OpenFileDialog;
                openFileDialog1->InitialDirectory = "D:\\hoge";
                openFileDialog1->Filter = "All files (*.*)|*.*";
                openFileDialog1->FilterIndex = 2;
                openFileDialog1->RestoreDirectory = true;
                if ( openFileDialog1->ShowDialog() == ::DialogResult::OK )
                        {
                                if ( (fs = openFileDialog1->OpenFile()) != nullptr )
                                        { 
                                        System::IO::BinaryReader ^ binReader = gcnew BinaryReader(fs);
                                        //文字変数を12バイト確保
                                        unsigned char c[11];
                                        int i = 0;
                                        // ファイルの終わりまで
                                        while(binReader->PeekChar() != -1)
                                        {
                                                //配列に1バイト読込む
                                                c[i] = binReader->ReadByte();
                                                // テキストに1バイト分の16進表記文字列を追加
                                                textBox1->Text += System::String::Format("{0:X2}" + " ", c[i]);
                                                i++;
                                        }
                                binReader->Close();
                                } 
                        }
                }


hoge  2006-04-30 10:50:07  No: 61573

Blueさん対応ありがとうございます
例外エラーの原因がなんとなくですが分かった気がします
修正前  while(binReader->PeekChar() != -1)

修正後  while(i < 12)
として読込むデータ数と書込むデータ数を合わせたら、例外エラーが出ませんでした
数の不一致に原因があるようです、後はファイルサイズを取得してmemst関数のような
ものが使えれば解決できるかもしれません。


Blue  2006-04-30 11:00:07  No: 61574

おそらく、ファイルの中身が 11 バイト以上あったため、
12バイト目を格納する時にエラーが発生したのでしょう。

ファイルのサイズは
fs->Length
で取れますので、

array< unsigned char >^ data = gcnew array< unsigned char >( ( int )fs->Length );

として、格納領域を確保します。

代入時は普通の配列のように代入できます。

ただし、C言語の配列とarray<〜>とは違いますので、unsigned charのポインタとしてほしい場合は普通に

unsigned char* data = new unsigned char[ ( size_t )fs->Length ];

として領域を確保してください。
そして、適切なところで delete[] data; してください。


通りすがり@もはや通りすがりじゃない気が  2006-04-30 14:13:12  No: 61575

CryptoAPIを使ってもいいなら
CryptBinaryToStringっていう便利なAPIがあります。
アスキー表示つけたりアドレスつけたりもフラグ指定だけでさくっと…


hoge  2006-05-01 01:12:19  No: 61576

Blueさんどうもありがとうございました、大変勉強になりました
通りすがり@もはや通りすがりじゃない気がしてきたさん
どうも、情報ありがとうございました
CryptBinaryToStringをgoogle日本語で検索したら3件しかヒットしませんでしたが
内容は大体理解できました。


※返信する前に利用規約をご確認ください。

※Google reCAPTCHA認証からCloudflare Turnstile認証へ変更しました。






  このエントリーをはてなブックマークに追加