- ベストアンサー
バイナリファイルの内容を、そのままテキストファイルに出力する方法
環境:VC2005 バイナリファイルのデータが以下の通りです。 (ex):41 22 5D 0D 8A 71 05 0A Cプログラムで、バイナリファイルのデータを読み込み、 char* test_data = (char*)"41225D0D8A71050A"; と、等価となるtest_data変数を作成したいのですが、 どのようにすれば良いのでしょうか。
- みんなの回答 (6)
- 専門家の回答
質問者が選んだベストアンサー
No.4の方が使っている test_data というのは、No.2の方が配列として定義したやつですよね。 だとしたら、後で test_data += 2 というふうに値を変更することはできません。 test_data += 2 というのは test_data = test_data + 2 同じ意味です。 コンパイル時に警告やエラーが出るかどうかはわかりませんが、C言語では配列を指すtest_dataのような変数に、後から別のアドレスを代入することはできません。(ポインタなら後から代入できます) char buff[8]; char *test_data = buff; とすれば test_data に後から別の値(アドレス)を代入することができます。 sprintfを使わないで質問にある処理を行うを次のようになります。(作業ディレクトリにあるtest.datというファイルを処理するとする) int main(void) { FILE *fp; unsigned char buff[8]; // バイナリデータのための配列 char test_data[16]; // 文字列のための配列 char data[] = "0123456789ABCDEF"; // 変換のための16進数資料のようなもの int count; fp = fopen("test.data", "rb"); fread(buff, 1, 8, fp); for(count = 0; count < 8; count++) { test_data[count * 2] = data[buff[count] >> 4]; // 上位4ビットの値(16進数の16の位)を文字にする test_data[count * 2 + 1] = data[buff[count] & 0x0f]; // 下位4ビットの値(16進数の1の位)を文字にする } return 0; } 戻す処理 int main(void) { char test_data[16] = "11AB849FE2CDE593"; char buff[8]; int temp[2]; int count; int i; for(i = 0; i < 16; i += 2) { for(count = 0; count < 2; count++) { if (test_data[i + count] < '9') { temp[count] = test_data[i + count] - 'A' + 10; } else { temp[count] = test_data[i + count] - '0'; } } buff[i] = temp[0] * 16 + temp[1]; } return 0; } ※どちらも、例外処理はしてません。
その他の回答 (5)
- SnowShower
- ベストアンサー率40% (140/348)
No4.です。 >等価のご認識ですが、1番に該当すると思います。 >1.char *testの指し示すアドレスに「文字列」"41225D0D8A71050A"を保存する。 わかりました。 でしたらNo.2の方の回答で問題ないはずです。 少し改良すると、 for(i =0; i<8; i++) { size = fread(buf, 1, 1, infp); sprintf(test_data,"%02X", buf); test_data += 2; } ---------- size = fread(buf, 1, 8, infp); for(i =0; i<8; i++) { sprintf(test_data,"%02X", buf[i]); test_data += 2; } のようにループ可もできます。
お礼
ありがとうございます。 size = fread(buf, 1, 8, infp); for(i =0; i<8; i++) { sprintf(test_data,"%02X", buf[i]); test_data += 2; } をやってみたのですが、出来ずにはまっていた ところ、No.5さんのご回答で、やり方がわかりました。
補足
ありがとうございます。 すぐ確認します。 あ、それとなんですが、、 size = fread(buf, 1, 8, infp); for(i =0; i<8; i++) { sprintf(test_data,"%02X", buf[i]); test_data += 2; } をして出来たtest_dataを、今度は元に戻す方法(次はバイナリで読み込んだ形)にするのに、一発で変換できるsprintfみたいな方法はありますか?それとも、1文字ずつ読み込んで変換していくしかないのでしょうか?
- SnowShower
- ベストアンサー率40% (140/348)
一応確認です。 >char* test_data = (char*)"41225D0D8A71050A"; >と、等価となるtest_data変数を作成したいのですが、 この「等価」の認識を教えてもらえませんか? 1.char *testの指し示すアドレスに「文字列」"41225D0D8A71050A"を保存する。 2.char *testの指し示すアドレスに「文字コード」「0x41,0x22,0x5D,0x0D,0x8A,0x71,0x05,0x0A」を保存する。 3.char *testの指し示すアドレスに「数値」で「0x41225D0D8A71050A」を保存する。 4.char *testの指し示す「アドレス」を0x41225D0D8A71050Aにする。 5.その他
補足
等価のご認識ですが、1番に該当すると思います。 char* test_data = (char*)"41225D0D8A71050A"; と宣言すると、 if( *test_data == '4') { 処理1 } というように、1文字に対して処理が出来るのですが、 fread("wb")でバイナリファイルを読み出しますと、 配列のデータ(上記の例で言うと2番ですかね)になってしまいます。 (*test_dataを参照すると、0x41が入ってしまいます) ファイルから読み出した値を、 以下のようなデータ構造で持ちたいです。 *test_data = '4' *(test_data+1) = '1' *(test_data+2) = '2' ・ ・略 ・ *(test_data+14) = '0' *(test_data+15) = 'A'
- Lchan0211
- ベストアンサー率64% (239/371)
No.2です。 訂正 ×size = fread(buf, 1, 1, infp); ↓ ○size = fread(buf, 1, 8, infp);
- Lchan0211
- ベストアンサー率64% (239/371)
これは、バイナリデータをそのまま出力ではなく 16進数の文字列で出力したいということだと思うので、 ---------------------------------- FILE *infp; unsigned char buf[8]; char test_data[17]; infp = fopen(ファイル名, "rb"); size = fread(buf, 1, 1, infp); sprintf(test_data,"%02X%02X%02X%02X%02X%02X%02X%02X", buf[0],buf[1],buf[2],buf[3],buf[4],buf[5],buf[6],buf[7]); fclose(infp); ---------------------------------- という感じだと思います。
お礼
やりたいことが出来ました! このたび、本当にありがとうございました。
補足
私もこれと同じことをやろうとしてたのですが、 そのときは、 sprintf(test_data, "%s%s"・・・, buf[0],buf[1] って感じでやっていたのかも知れません。 もう一度、試してみます。 ありがとうございます^^
こんな感じになります。 ----------------- FILE *infp; char test_data[8]; infp = fopen(ファイル名, "rb"); size = fread(test_data, 1, 8, infp); fclose(infp);
補足
私も同じことをやったのですが、 駄目でした^^;
お礼
ありがとうございます。 やりたい事が出来ました! ちなみに、戻す処理の方を、以下のように変更してます。 int temp[2]; int count; int i,j; j = 0; for(i = 0; i < (size * 2); i += 2) { for(count = 0; count < 2; count++) { if (pTxt_buff[i + count] <= '9') { temp[count] = pTxt_buff[i + count] - '0'; } else { temp[count] = pTxt_buff[i + count] - 'A' + 10; } } pBin_buff[j] = temp[0] * 16 + temp[1]; j++; } このたび、本当にありがとうございました。