ページ 1 / 1
fwrite
Posted: 2012年3月03日(土) 15:58
by kureid
http://9cguide.appspot.com/17-02.html こちらを参考にして勉強してたのですが
fwriteでバイナリファイルをきちんと書き込めません
http://csskureid.mys-web.net/test.dat
こうなってしまいます。
コードは
コード:
#include <stdio.h>
int main(void)
{
int buf[] = { 1,10,100,1000 };
FILE *file;
file = fopen("test.dat","wb");
fwrite(buf,sizeof(buf),1,file);
fclose(file);
return 0;
}
です
誰か助けてください
Re: fwrite
Posted: 2012年3月03日(土) 16:04
by box
kureid さんが書きました:
こうなってしまいます。
こうなってしまう、というのは、文字化けのように見えてしまう、ということでしょうか。
バイナリーモードで書き出したのですから、文字化けのように見えるのは当然だと思います。
それとも、バイナリーファイルを参照できるエディターか何かで見ても中身が正しくない、ということでしょうか。
Re: fwrite
Posted: 2012年3月03日(土) 16:12
by kureid
そうです
バイナリエディタで開いて文字化けしてしまいます
Re: fwrite
Posted: 2012年3月03日(土) 16:38
by とっち
コード:
int main(void)
{
FILE *file;
int c;
file = fopen("test.dat","rb");
while(c=getc(file)!=NULL)
printf("%d\n",c);
fclose(file);
return 0;
}
kureidさんのコードを実行してtest.datを作成し、
このようなコードで結果を確認すると、
1
と表示されました。
きちんと表示されているのでkureidさんがもしかしたら
バイナリエディタの設定か何かを間違っているのではないでしょうか?
Re: fwrite
Posted: 2012年3月03日(土) 16:41
by box
kureid さんが書きました:
バイナリエディタで開いて文字化けしてしまいます
バイナリーエディターには「ファイルの中身を16進でダンプする」という機能が
おそらくあると思います。
16進での表示内容を教えてください。
Re: fwrite
Posted: 2012年3月03日(土) 16:47
by box
とっち さんが書きました:
このようなコードで結果を確認すると、
1
と表示されました。
きちんと表示されているのでkureidさんがもしかしたら
それだけの結果から、どうして「きちんと表示している」と判断されたのか、
疑問があります。
10とか100とか1000については見なくてもいいのでしょうか。
とっち さんが書きました:
コード:
int c;
while(c=getc(file)!=NULL)
NULLとint型のcとを比較している(ように見える)点にも、疑問があります。
Re: fwrite
Posted: 2012年3月03日(土) 17:20
by とっち
>boxさん
失礼しました
確かに僕の方法だとだめですね
名誉挽回のためもう一つ投下
コード:
#include <stdio.h>
int main(void)
{
FILE *file;
int c[10];
file = fopen("test.dat","rb");
fread(c,sizeof(c),10,file);
fclose(file);
for(int i=0;i<10;i++)
printf("%d\n",c[i]);
return 0;
}
ものすごく汚いし、ひどいプログラムですが、
kureidさんのコードでtest.datを作成した場合、
1,10,100,1000
を確認できます。
ですので、kureidさんのプログラムには問題はないかと思います。
Re: fwrite
Posted: 2012年3月03日(土) 17:27
by box
kureid さんが書きました:
バイナリエディタで開いて文字化けしてしまいます
先ほどの回答に補足します。
バイナリーエディターという、バイナリーファイルの中身を見ることができるソフトウェアを
使っているとしても、今回のファイルを「テキストファイルとして」開くと、文字化けしているように
見えるのは、当たり前です。
ですので、「16進の内容を教えてください」とお願いしております。
ていうか、そもそも、どういう表示結果になることを望んでおられるのでしょうか。
Re: fwrite
Posted: 2012年3月03日(土) 17:31
by kureid
皆さん回答ありがとうございます
使ってるバイナリエディタはStirling
それでtest.datを開き16進数で開くと
左から
01 00 00 00 0A 00 00 00 64 00 00 00 E8 03 00 00 .......d.......
となります
Re: fwrite
Posted: 2012年3月03日(土) 17:40
by box
kureid さんが書きました:
それでtest.datを開き16進数で開くと
左から
01 00 00 00 0A 00 00 00 64 00 00 00 E8 03 00 00 .......d.......
となります
正しいです。
1,10,100,1000をそれぞれ4バイトの16進数で表現すると(バイト間に空白を入れると)
00 00 00 01
00 00 00 0A
00 00 00 64
00 00 03 E8
となります。表示結果から推測すると、質問者さんの利用しているPCのCPUは
おそらくリトルエンディアンでありましょう(エンディアン endian について興味があればググってみてください)。
ですので、バイナリーファイルに格納する際にバイト順が逆転して
01 00 00 00
0A 00 00 00
64 00 00 00
E8 03 00 00
となったわけで、間違いでも何でもありません。
Re: fwrite
Posted: 2012年3月03日(土) 17:49
by ISLe
とっちさんの最初のコードは、NULLじゃなくてEOFと比較すれば、1バイトずつ10進数で表示するプログラムとして正しくなります。
Re: fwrite
Posted: 2012年3月04日(日) 08:31
by beatle
とっち さんが書きました:
名誉挽回のためもう一つ投下
コード:
#include <stdio.h>
int main(void)
{
FILE *file;
int c[10];
file = fopen("test.dat","rb");
fread(c,sizeof(c),10,file);
fclose(file);
for(int i=0;i<10;i++)
printf("%d\n",c[i]);
return 0;
}
本題ではありませんので恐縮ですが、一応コメントしておきます。
コード:
fread(c,sizeof(c),10,file);
と書くと、test.datが配列cより大きい場合、最大でsizeof(c) * 10バイト分読み込んでしまいますのでバッファーオーバーフローします。
コード:
fread(c, sizeof(int), 10, file);
などと書く方がいいでしょう。
Re: fwrite
Posted: 2012年3月04日(日) 13:47
by kureid
みなさん回答ありがとうございました