• ベストアンサー

ファイルから読みこんで構造体に格納する、

shohinというファイルに RX-100 odango_tsumeawase 3000という のが 五行ならんでいるのですが、 これを読み込んで struct shohin{ char code[10]: char name[40]; int price; } にファイルから読みこんで構造体配列に 格納したいのですが、構造体配列に格納する やりかたがわかりません。 構造体配列は struct shohin list[];というのを宣言しています。 ファイルから一行読み込んで fprintf()を使おうと思うのですが、 それはできますか? メンバ毎に格納したいのですが、 それがわかりません お願いします。

質問者が選んだベストアンサー

  • ベストアンサー
  • BLUEPIXY
  • ベストアンサー率50% (3003/5914)
回答No.2

#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のように書きます。

Judau_MSZ-010
質問者

お礼

ありがとうございます! 助かりました。

その他の回答 (2)

  • gimmick
  • ベストアンサー率49% (134/270)
回答No.3

のんびりコードを書いてたら、#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);   } }

Judau_MSZ-010
質問者

お礼

ありがとうございます。

  • anmochi
  • ベストアンサー率65% (1332/2045)
回答No.1

fprintf? fscanfじゃなくって? fscanfを使うとしたら下のようになるのかな。 unsigned long i; while(fscanf("%s %s", list[i].code, list[i].name))  i++;  ただ、1行1レコードのテキストファイル読み込みはやはりルーチン化してエラーチェックを行いたい。fgetsで1行読んで、strstrなりでスペースを探し、データがちゃんと2列あるかどうか、桁数が大きすぎないか等々制御してあげるべきだろう。

Judau_MSZ-010
質問者

お礼

ありがとうございます。

関連するQ&A