バイナリファイル

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
ざこ

バイナリファイル

#1

投稿記事 by ざこ » 16年前

先日バイナリファイルについてご質問させていただいたのですが、先日の件は納得できたのですが
思うように実行できないのでご質問させていただきます。
int main(void) 
{
  FILE *file;
  long buf[100];

  file=fopen("ファイル名","rb");
  fread(buf,sizeof(long),1,file);
  printf("%x",buf);

  fclose(file);
  
   }
基礎プログラムだと思いますがこのプログラムは
ファイルから4バイトずつを1回読み込んでbufに格納しprintfで16進数で表示するというプログラムだと思います。

この読み込んだファイルの内容は
000000 90 7D 8C 60 50 00 BE 02・・・
という内容です。
ということは 90 7D 8C 60  と4バイト分読み込み表示されると思うのですが・・
実際にbuf内に入っているのは 0x0012fdec となっています。これは何が間違っているのでしょうか?

御津凪

Re:バイナリファイル

#2

投稿記事 by 御津凪 » 16年前

> printf("%x",buf);

ここで渡している buf が問題です。
printf では、基本、値で渡します(文字列はポインタで渡す)、
buf は配列なので、これは先頭のポインタを渡していることになります。
(表示されている値はポインタ値です)

なので、この場合では、
printf("%x",*buf);
と書くのが処理として正しいです。

あと、16進数8桁表示(幅固定)で表示するには、"%x"を、"%8x"か"%08x"にすると良いでしょう。

ざこ

Re:バイナリファイル

#3

投稿記事 by ざこ » 16年前

1つご質問を
>buf は配列なので、これは先頭のポインタを渡していることになります。

について少し詳しく教えてください。

表示された内容がポインタなのはわかります。

toyo

Re:バイナリファイル

#4

投稿記事 by toyo » 16年前

printf("%x", buf[ 0 ]);
でもいいです

御津凪

Re:バイナリファイル

#5

投稿記事 by 御津凪 » 16年前

> >buf は配列なので、これは先頭のポインタを渡していることになります。
>
> について少し詳しく教えてください。

配列は、連続したデータを持ちます。
連続したデータということは、アドレスが隣り合わせになっていることを示します。
そして、配列の変数は、配列そのものを持っているわけでなく、配列へのポインタを指しています。

ここで、先頭のポインタ、というのは、「配列」の0番目を指すポインタのことですね。
long buf[100];
と、配列を用意した時、
buf[0] は先頭のデータを指します。
*buf も先頭のデータを指します。
先頭のポインタを指す時は、 &buf[0] で表せます。
と、いうことは、 buf でも先頭のポインタを指します。

これは、他の型の配列でも同じです。
文字列も配列の一つなので、このことが同様に当てはまります。

# ちなみに、 *(buf+1) は buf[1] と同じく、(buf+10) は、&buf[10] と同じです。

ざこ

Re:バイナリファイル

#6

投稿記事 by ざこ » 16年前

成る程、配列についてちゃんとわかってなかったみたいです。ありがとうございました。

最後にもう1つだけご質問なのですが、上記の例では4バイトを1回ずつ読み込み表示しました
結果 608C7D90となり、望む結果になりました。
ただ1バイトごとに4回読み込んでも同じ結果が得られるのでしょうか?
というのも2バイトのときはsizeof(short),4バイトのときはsizeof(long)と読み込むバイト数ごとに
変数を用意するというやり方もありますが、1バイトを4回読み込むなら用意する配列は1個ですむのだろうか・・と思いました。
int main(void) 
{
  FILE *file;
  char buf[100];

  file=fopen("ファイル名","rb");
  fread(buf,sizeof(char),4,file);
  printf("%8x",*buf);

  fclose(file);
  
   }
としましたが結果は fffff90 となり一致しません。
基本的なことで申し訳ないのですがしっかり理解しておきたいので教えてください。

non

Re:バイナリファイル

#7

投稿記事 by non » 16年前

>printf("%8x",*buf);
これでは buf[0]のみ表示してます。1バイトなのに8桁も使って。

printf("%02x",buf[0]);
printf("%02x",buf[1]);
printf("%02x",buf[2]);
printf("%02x",buf[3)];

ざこ

Re:バイナリファイル

#8

投稿記事 by ざこ » 16年前

これはお恥ずかしい間違いのようです・・
ありがとうございました。

御津凪

Re:バイナリファイル

#9

投稿記事 by 御津凪 » 16年前

読み込み自体は正しいです。ちゃんと4バイト読み込んでいます。
ただし、char 型は1バイトで-128~127までの数値を表現する型なので、
0x90 を読み込むと、10進数は char 型では -122 となり、その値で表示されています。

簡単に言うと、char 型では表現できる数が小さいので、正しく printf に渡せなかったわけです。

望みどおりの値を表示するには、
printf("%02x%02x%02x%02x",buf[0],buf[1],buf[2],buf[3]);
と、出力するか、型変換を使って強引に、
printf("%08x",*(long*)buf);
とすることで表示することが出来ます。

non

Re:バイナリファイル

#10

投稿記事 by non » 16年前

ここまで疑問をもったら、次はエンディアンですね。
ググってみましょう。

toyo

Re:バイナリファイル

#11

投稿記事 by toyo » 16年前

%xでchar型を表示するとintに変換されるので負の数がffffff90みたいになります
unsigned char buf[100];
にすればいいでしょう
(C99では%hhxでchar型の変換が出来ますが)

閉鎖

“C言語何でも質問掲示板” へ戻る