- ベストアンサー
fwrite文について
char型で宣言した配列の方はうまくいきましたが、構造体を用いたfwrite文がうまく出力されません。 どうしてでしょうか? #include <stdio.h> #include <string.h> #include <stdlib.h> struct ll{ char name[20]; int ten[3]; }list[3] = { {"aaa", 11}, {"bbb",22}, {"ccc",33} }; FILE *fpbin, *fpcsv; /*FILE構造体(グローバル変数)*/ void main(void) { char i[] = {'a','b'}; fpbin = fopen("data.txt","w"); //fwrite(&i,sizeof(char),2,fpbin); fwrite(&list[0].name,sizeof(struct ll),2,fpbin); fclose(fpbin); }
- みんなの回答 (3)
- 専門家の回答
質問者が選んだベストアンサー
プログラムの想定動作がわからないのですが、 問題がいくつかあります。 (1)構造体配列の宣言の所、 struct ll{ char name[20]; int ten[3]; }list[3] = { {"aaa", 11}, {"bbb",22}, {"ccc",33} }; これは、charの方はいいのですが、intの配列の方が 正しく初期化されていません。 struct ll{ char name[20]; int ten[3]; }list[3] = { {"aaa", {1,1,1}}, {"bbb",{2,2,2}}, {"ccc",{3,3,3}} }; のように、入れ子の配列を使って初期化します。 (2) fwrite(&list[0].name,sizeof(struct ll),2,fpbin); のところ、.nameは不要で fwrite(&list[0],sizeof(struct ll),2,fpbin); とします。もっとも、指すアドレスは同じなので、 直さなくても動きますが…。 (3)出力ファイルをdata.txtとしています。 文法的にはtxtファイルという拡張子で問題ないのですが、 fwriteで出力されるものは基本的にバイナリファイルです。 これで書き出したものをテキストエディタで見ると、charの配列は読めるけれど、 intやdoubleなどの数値はコンピュータの内部状態のまま出力されるため、 意味不明な記号になります。 (fwrite()で書き込んだファイルは、基本的にfread()で 読み込むべきデータファイルです。) バイナリファイルを読むときは「バイナリエディタ」というツールがあります。 必要ならばVectorあたりからダウンロードしてください。 テキストファイルとして書き込みたいのなら、 fwrite()ではなくてfprintf()などの関数を使います。 以上のことを参考にして、書き直してみてください。
その他の回答 (2)
- liar_adan
- ベストアンサー率48% (730/1515)
> printf("p = %s ten = %d\n", list[0].name, list[0].ten); ここのところにある list[0].ten は、あくまで「int型の配列」であって、int型ではありません。 配列の中に入っているint型を表示させたいなら printf("p = %s ten = %d\n", list[0].name, list[0].ten[0]); のようにします。 配列に入っている値を三つとも表示するときは printf("ten1 = %d, ten2 = %d, ten3 = %d\n", list[0].ten[0], list[0].ten[1], list[0].ten[2]); のようにします。
お礼
fwriteとfreadはバイナリファイルを扱うものなのでfpbin = fopen("data.txt","w+");ではなくfpbin = fopen("data","w+b");でした。freadの戻り値もきちんと表示されました。 どうもお騒がせしました。
補足
返答ありがとうございます。きちんと表示されました。 ところで、fwriteとfreadの戻り値が正常時は第三引数に一致するとなっていますが、fwriteの方はきちんと表示されますが、freadの方が0となってしまいます。なぜでしょうか? #include <stdio.h> #include <string.h> #include <stdlib.h> struct ll{ char name[20]; int ten[3]; }list[3] = { {"aaa", {1,1}}, {"bbb",{2,2}}, {"ccc",{3,3}} }; FILE *fpbin, *fpcsv; /*FILE構造体(グローバル変数)*/ void main(void) { char i[] = {'a','b'}; int su; fpbin = fopen("data.txt","w+"); //fwrite(&i,sizeof(char),2,fpbin); su = fwrite(&list[0],sizeof(struct ll),3,fpbin); printf("su = %d", su); fpbin = fopen("data.txt","r");fclose(fpbin); su = fread(&list[0],sizeof(struct ll),3,fpbin); printf("su = %d", su); printf("name = %s ten1 = %d, ten2 = %d\n",list[0].name, list[0].ten[0], list[1].ten[1], list[0].ten[2]); fclose(fpbin); }
- BLUEPIXY
- ベストアンサー率50% (3003/5914)
配列はlist[3]なのに、 書き出す個数が2になっています。 あと、#1の方が言われているように、 ちゃんと、int型のデータを初期化しておいた方が良いでしょうね。 読み出した時にゴミなのかデータなのかわかりませんから。
補足
詳しい解説ありがとうございます。おかげでよく分かりました。ところでfread()処理を行ってファイルから読んで表示させようとしたところ、文字の方はきちんと表示されましたが、数字の方が表示されません。 どうしてでしょうか? #include <stdio.h> #include <string.h> #include <stdlib.h> struct ll{ char name[20]; int ten[3]; }list[3] = { {"aaa", {1,1,1}}, {"bbb",{2,2,2}}, {"ccc",{3,3,3}} }; FILE *fpbin, *fpcsv; /*FILE構造体(グローバル変数)*/ void main(void) { fpbin = fopen("data","w+"); fwrite(&list[0],sizeof(struct ll),3,fpbin); fread(&list[0],sizeof(struct ll),1,fpbin); printf("p = %s ten = %d\n", list[0].name, list[0].ten); fclose(fpbin); }