- ベストアンサー
ファイルから読みこんで構造体に格納する、
shohinというファイルに RX-100 odango_tsumeawase 3000という のが 五行ならんでいるのですが、 これを読み込んで struct shohin{ char code[10]: char name[40]; int price; } にファイルから読みこんで構造体配列に 格納したいのですが、構造体配列に格納する やりかたがわかりません。 構造体配列は struct shohin list[];というのを宣言しています。 ファイルから一行読み込んで fprintf()を使おうと思うのですが、 それはできますか? メンバ毎に格納したいのですが、 それがわかりません お願いします。
- みんなの回答 (3)
- 専門家の回答
質問者が選んだベストアンサー
#include <stdio.h> #define LISTMAX 5 struct shohin { char code[10]; char name[40]; int price; }; struct shohin list[LISTMAX]; void main(void){ int i=0; FILE *fp; char buff[128]; fp=fopen("shohin","r"); while(NULL!=(fgets(buff,128,fp))){ if(i==LISTMAX){ printf("確保した以上にデータがあります\n"); break; } sscanf(buff,"%s %s %d", list[i].code, list[i].name, &list[i].price); printf("list[%d]:\n\tcode:%s\n\tname:%s\n\tprice:%d\n", i, list[i].code, list[i].name, list[i].price); i++; } fclose(fp); } こんな感じ、 ちなみに、質問文でcode[10]の後が:になってます。 struct shohin { ... } の後に;が要ります。 初期化するのでなく、ファイルから読むのだから list[]には、確保する数が必要です。 サンプルで、一行読んでからsscanfを使っています。 scanfは、あんまり信用ならないからです sscanfは、空白区切りのデータの読み込みに軽易に使えます。 また、あらかじめ配列で確保するのでなく 動的に確保する場合には、mallocを使います。 その場合は、ポインタで受けて各メンバーへは listp->codeのように書きます。
その他の回答 (2)
- gimmick
- ベストアンサー率49% (134/270)
のんびりコードを書いてたら、#2の方に先を越されていまいました。基本的に同じ事をしていますが、せっかく書いたので投稿します。 #include <stdio.h> #define ITEM_MAX 1024 #define FILE_PATH "D:\\item_list.txt" typedef struct _Item Item; int ReadItems(FILE* fp, Item items[], int max); void PrintItems(FILE* fp, const Item items[], int cnt); typedef struct _Item{ char code[10]; char name[40]; int price; } Item; int main(int argc, char* argv[]) { FILE* fp; Item items[ITEM_MAX]; int cnt; /*ファイルオープン*/ fp = fopen(FILE_PATH, "r"); if (fp == NULL) { printf("file open error!\n"); return 1; } /*入力*/ cnt = ReadItems(fp, items, sizeof(items)/sizeof(items[0])); fclose(fp); if (cnt == 0) { printf("no data!\n"); return 1; } else if (cnt < 0) { printf("file format error! line:%d\n", -cnt); return 1; } /*出力*/ PrintItems(stdout, items, cnt); return 0; } /*データ取得用関数*/ int ReadItems(FILE* fp, Item items[], int max) { int i = 0; char buf[1024]; char extra[1024]; while (fgets(buf, sizeof(buf), fp) != NULL) { int ret = sscanf(buf, "%9s%39s%8d%s", items[i].code, items[i].name, &items[i].price, extra); i++; if (ret != 3) return -i; if (i == max) break; } return i; } /*データ出力用関数*/ void PrintItems(FILE* fp, const Item items[], int cnt) { int i = 0; for (i = 0; i < cnt; i++) { fprintf(fp, "code:%s name:%s price:%d\n", items[i].code, items[i].name, items[i].price); } }
お礼
ありがとうございます。
- anmochi
- ベストアンサー率65% (1332/2045)
fprintf? fscanfじゃなくって? fscanfを使うとしたら下のようになるのかな。 unsigned long i; while(fscanf("%s %s", list[i].code, list[i].name)) i++; ただ、1行1レコードのテキストファイル読み込みはやはりルーチン化してエラーチェックを行いたい。fgetsで1行読んで、strstrなりでスペースを探し、データがちゃんと2列あるかどうか、桁数が大きすぎないか等々制御してあげるべきだろう。
お礼
ありがとうございます。
お礼
ありがとうございます! 助かりました。