• ベストアンサー

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

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

  • 構造体のあるメンバを基準にソートするには?

    以下のように定義した構造体(下の構造体は入れ子になっている)を必要な時に動的に割り当てた後(デー多数は不定)、たとえば、商品価格を基準に降順、昇順に並び替える機能を追加したいのですが、どのように解決したらよろしいでしょうか? /* 現在の日時を格納する構造体 */ typedef struct time_type{ int year; int month; int day; }time_type; /* 商品の情報を格納する構造体 */ typedef struct shohin_type{ int code; /* 商品コード */ int price; /* 商品価格 */ char *name; /* 商品名 */ int flag; /* フラグ */ struct time_type date; /* 登録日 */ struct shohin_type *before; /* 前の構造体のアドレス */ struct shohin_type *next; /* 次の構造体のアドレス */ }shohin_type;

  • 構造体について

    凄く初歩的な質問で申し訳ありませんが… 入門書の構造体のところで 以下のようなプログラムの例がありました。 #include <stdio.h> struct seiseki { /* 構造体の宣言 */ int no; char name[20]; double average; }; int main(void) { int i; struct seiseki seito1, seito2[20]; /* 構造体変数と構造体配列の宣言 */ >char name[20] というのは、NAMEの領域を20文字 確保すると言うことですよね? >struct seiseki seito1, seito2[20] ここの箇所が分からないのですが seito2[20]の20というのは どうして20なのですか? NAMEだけではないので もっと大きな数字になるような気がするのですが… またseito1の方は どうして数字が何もないんですか? 考え違いをしているところを ご指摘して頂ければ幸いです。

  • 構造体で・・・・

    構造体は配列を使用せずメモリ領域を獲得する関数を使用すること、 *構造体内部のメンバ名には配列を用いて良い。  という、条件があるのですが場合はどのようにすればよろしいでしょうか? どなたか教えてください。 構造体は以下のようになってます。 /*構造体の定義*/ struct seiseki{   char name[20];   int eig;   int suu;   int kok;   char rank[3]; };

  • ファイルから構造体へデータを格納(動的メモリ割り当て)

    C言語の勉強をしいております。 typedef struct address { char names[32]; /* 名前 */ char tels[32]; /* 電話番号 */ struct address *prev; /* 前のリスト */ struct address *next; /* 次のリスト */ }Address; という構造体へ、ファイルから読み込んだテキストデータ(名前と電話番号がTABで区切られている)を格納したいのですが、配列ではなく、動的にメモリを確保しながら格納する方法を教えていただけないでしょうか? 処理の流れとしては、 ・1つめの構造体の*prevにはnullを入れておく。 ・1つめの構造体へファイルの1件目のデータを格納する。 ・ファイルのデータがまだある場合には、malloc関数を使ってメモリを確保し、malloc関数からの戻り値を1つめの構造体の*nextへ格納する。 ・構造体へ2件目のデータを格納する。 このような感じだろうという程度しか分からず、ソースも書けずにいます・・・。 配列を使用したサンプルはあるんですが、動的に処理を行う方法を教えていただけないでしょうか? よろしくお願いいたします。

  • C言語の文字列を含んだ構造体

    下記のサイトに構造体のことが書かれています。 http://www.isl.ne.jp/pcsp/beginC/C_Language_14.html その中の (3)構造体の初期化 の記述で  //構造体の型宣言  struct student{   int no; // 学籍番号   char name[256]; // 氏名   int year; // 学年   char student_class[256]; // クラス  }; と書かれています。 次の(4)構造体のデータ参照では、  //構造体の型宣言  struct OLD{   int no; //番号   char *name; //名前   int s_year; //年   char s_class; //クラス  }; と書かれています。 ここで質問です。 前者の名前は char name[256] ですが、 後者の名前は char *name になっています。 name[256] と *name では何が違うのでしょうか? どういうときに使い分けるのでしょうか?

  • ファイルから読み込んだデータを構造体に格納できますか?

    1レコード19バイトのファイルを 読み込む処理を行っています。 地区名10バイト 県名8バイト 改行1バイト このデータをdouken(構造体)に格納したいのですが >while (fgets(dou,19,fp) != NULL){ で、エラーになってしまいます。 どのようにしたら ファイルから読み込んだデータを 構造体に格納できますか? #include<stdio.h> #include <stdlib.h> struct douken { char tiku[10]; char ken[8]; } main(void){ FILE *fp; struct douken dou[100]; int i; fp = fopen("ex3.fil","rb"); if ( fp == 0 ){ printf("can't open\n"); exit(1); } while (fgets(dou,19,fp) != NULL){ ・ ・ ・

  • 構造体について

    以下のような構造体の宣言が合ったとき struct list { int a; char b[20]; struct list *next; }; struct list *add_list( int a, char *str, struct list *head );・・・1 struct list *del_list( int a, struct list *head );・・・2 1は引数の数が同じため問題ないのですが、2はどういう意味になるのでしょう?

  • C#で構造体の配列を持った構造体を使いたいのですが

    C#で構造体の配列を持った構造体を使いたいのですが Cならば struct xyz { struct abc _abc[32]; int index; }; struct abc { int a; int b; int c; }; struct xyz _xyz[8]; xyz[0]._abc[3].b = 1; のような使い方で という感じで やっていた事を C#で 同じような事をやろうとしても うまくいきません うまくやる方法をどなたかご存知ないでしょうか Visual Studio 2005行った場合 コンパイルで 構文エラーです。不適切な配列の宣言子です。マネージ配列を宣言するには、次元指定子を変数の識別子の前に指定します。固定サイズ バッファ フィールドを宣言するには、フィールド型の前に fixed キーワードを使用します となり fixed をつけると 固定サイズ バッファの型は次のうちの 1 つでなければなりません: bool、byte、short、int、long、char、sbyte、ushort、uint、ulong、float または double となってしまいます

  • 構造体のポインタにNULLが入らない

    typedef struct tag{ int number; char name[10]; struct tag *next; }DATA; という構造体があって、 DATA *p; と宣言し、 p->next == NULL; とすることはできないんですか? セグメンテーション違反になってしまうのですが。 pが指すnextにNULLを入れるにはどうしたらいいのでしょうか?

  • 構造体のリストをソートしたい。

    ある名簿のリストを作りました。 以下のような構造体で、 typedef struct meibo{ char name[10]; int old; struct meibo *next; }MEIBO; これを、ポインタp->next->nameをたどっていって、名前が辞書順になるようにリストを作ったのですが、 これを年齢順にソートして表示させたいんです。 どんな方法があるんでしょうか? 一旦すべてを配列に格納して、クイックソート…とかも考えたのですが、すごく領域をとるし、なんか2度手間(最初から配列に順に格納していけばよかったなぁ・・・と。 それでもやっぱり最初から名列順にするときから配列に入れておくほうがいいのでしょうか? 教えてください。 (最初から年齢を比較してリストを作れば・・ってのはなしで、名列順のリストが存在するものとしてください。)

専門家に質問してみよう