• 締切済み

C言語 構造体

以前にも構造体について質問させていただきましたが、より自由度の高い処理が必要となりご質問させていただきます。 よろしくお願いいたします。 以前のものは入力する項目数(列),行数(行)が前提にあるものでした。 テキストファイルを読み込んで、 構造体としてデータを読み込みたいのですが、 今回は項目数が不定のものです。 a.txt ------------------------- あああ,いいい,ううう ------------------------- とあれば あああ いいい ううう とカンマ抜きで得たい。(3項目) 次回読み込んだとき、 a.txt ------------------------- abc,def,g,h,i,jk ------------------------- とあれば、 abc def g h i jk とカンマ抜きで得たい。(6項目) 以前のものは下記のような感じです。 FILE *fp; FILE *file; struct seiseki seito[20]; char buf[1024]; fp = fopen("aaa.txt", "r"); i=0; while( fgets(buf, sizeof(buf), fp) ){ struct seiseki tmp; sscanf(buf,"%d %s %s %d %d %d",&tmp.no,tmp.lname,tmp.fname,&tmp.val[0],&tmp.val[1],&tmp.val[2]); seito[i++] = tmp; } for(i = 0; i < 3; i++) { printf("%d / %s %s / %d / %d / %d / %d\n", seito[i].no,seito[i].lname,seito[i].fname, seito[i].val[0], seito[i].val[1], seito[i].val[2], seito[i].val[0] + seito[i].val[1] + seito[i].val[2]); }

みんなの回答

  • fibre102
  • ベストアンサー率20% (6/29)
回答No.1

区切りの問題なら、fgetsで一行読んだあと、strtokで区切り文字を指定するとかはどうでしょう。 あと、サイズが不定については、単純にははじめから十分なサイズのバッファを用意しておけばよいと思います。 そうでなければ、要素が増えるたびに領域を割り当ててリンクをつないでいけばよいのでは? struct xx{ char name[XX]; struct xx *p_next ; } ;

関連するQ&A

  • 44行目: パラメータ '__format' は const signed char * 型として定義されているので int は渡せない(関数 main )

    ☆--------------ソース--------------☆ #include <stdio.h> struct seiseki { int no; char fname[20]; char lname[20]; int val[3]; }seito; int main(void) { int i,total; FILE *fp; FILE *file; struct seiseki seito[20]; char buf[1024]; fp = fopen("in.txt", "r"); i=0; while( fgets(buf, sizeof(buf), fp) ){ struct seiseki tmp; sscanf(buf,"%d %s %s %d %d %d",&tmp.no,tmp.lname,tmp.fname,&tmp.val[0],&tmp.val[1],&tmp.val[2]); seito[i++] = tmp; } printf("ID / NAME / 数(1) / 数(2) / 数(3) \n"); for(i = 0; i < 3; i++) { printf("%d / %s %s / %d / %d / %d\n", seito[i].no,seito[i].lname,seito[i].fname, seito[i].val[0], seito[i].val[1], seito[i].val[2]); } file = fopen("output.html","w"); fprintf(file ,"<HTML><HEAD></HEAD><BODY><table border=1 bodercolor=black cellspacing=0 width=700>\n"); fprintf(file ,"<tr bgcolor=#FF7575><td>ID</td><td>氏名</td><td>数(1)</td><td>数(2)</td><td>数(3)</td><td>合計点</td><td>平均点</td><td>偏差値</td><td>順位</td></tr>\n"); for(i = 0; i < 3; i++) { fprintf(file ,seito[i].lname); fprintf(file ,seito[i].fname); ☆省略☆ fprintf(file ,seito[i].val[0]); ☆省略☆ } fprintf(file ,"\n</table></BODY></HTML>\n"); return 0; }

  • C言語 構造体(2)

    ご質問です。 構造体で、あらかじめメンバ数を固定したものではなく、 テキストファイルを読み込んだときにメンバ数を変えて読み込みたいのです。 (カンマできりたい) aaa.txt ------------------------ あああ,いいい ------------------------ となっているときは、 tmp.nm[0]=あああ tmp.nm[1]=いいい となり、 kamoku.nm[0] kamoku.nm[1] をprintf。 aaa.txt --------------------------- あああ,いいい,ううう,えええ --------------------------- の場合は tmp.nm[0]=あああ tmp.nm[1]=いいい tmp.nm[2]=ううう tmp.nm[3]=えええ kamoku.nm[0] kamoku.nm[1] kamoku.nm[2] kamoku.nm[3] をprintf。 下記は動きません。。 よろしくお願いいたします。 #include <stdio.h> struct kamokumei { char nm[10]; }kamoku; int main(void) { int i,P,t; FILE *fp; struct kamokumei kamoku[20]; char buf[1024]; fp = fopen("aaa.txt", "r"); P=3; t=0; while( fgets(buf, sizeof(buf), fp) ){ struct kamokumei tmp; sscanf(buf, "%s", tmp.nm[t]); nm[t++] = tmp; } for(i = 0; i < P; i++) { printf("%s\n", kamoku.nm[i]); } return 0; }

  • 構造体のリスト

    ご質問させていただきます。 下記は拾ったソースをちょっとアレンジしたものなのですがエラーはなく動きます。 struct seiseki { int no; /* 学生番号 */ char name[20]; /* 氏名 */ double average; /* 平均値 */ }; int main(void) { int i; struct seiseki seito[20] = { { 1, "SAKURAI", 78.6 }, { 2, "NAGANO", 57.3 }, { 3, "TAKESHITA", 66.4 }, }; for(i = 0; i < 3; i++) { printf("%d %s %5.1f\n", seito[i].no, seito[i].name, seito[i].average); } return 0; } これを、もうちょっと応用を利かせ、 固定されているデータ部分 { 1, "SAKURAI", 78.6 }, { 2, "NAGANO", 57.3 }, { 3, "TAKESHITA", 66.4 }, をテキストファイルなどからfgetと組み合わせてデータを取りたいのです。 どうやればよいのかネット上を探してみたのですが、 なかなか似たようなものがありませんでした。 どうやればよいのでしょうか。 また、これは可能なのでしょうか。 教えてください。 また、参考になる書籍、URLなどもあれば併せて教えていただければ幸いです。

  • 構造体について

    凄く初歩的な質問で申し訳ありませんが… 入門書の構造体のところで 以下のようなプログラムの例がありました。 #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の方は どうして数字が何もないんですか? 考え違いをしているところを ご指摘して頂ければ幸いです。

  • 構造体の構造体 引数

    構造体の中の構造体の関数の引き渡し方法がわかりません。 下記ソースで試したのですが、うまくいきませんでした。 助言お願いいたします。 //repo.c #include <stdio.h> #include <string.h> #include <stdlib.h> #include <ctype.h> #define NUM 20 #define MAX 15 struct seiseki{ float shu[3]; }; struct seito{ char name[NUM]; int age; struct seiseki kekka; }; void input(struct seito *p); void s_input(struct seiseki *p); void ss_input(struct seiseki *data); int main(){ int i; struct seito data[2]; for(i=0;i<2;i++){ printf("------------------------------\n"); printf("%d人目",i+1); input(&data[i]); } printf("%f\n",data[0].kekka.shu[0]); printf("%f\n",data[0].kekka.shu[1]); printf("%f\n",data[0].kekka.shu[2]); //data[1]に格納できない。 printf("%f\n",data[1].kekka.shu[0]); printf("%f\n",data[1].kekka.shu[1]); printf("%f\n",data[1].kekka.shu[2]); return 0; } void input(struct seito *p){ printf("名前->"); scanf("%s",p->name); printf("年齢->"); scanf("%d",p->age); s_input(&(p->kekka)); } void s_input(struct seiseki *data){ printf("国語->"); ss_input(data); printf("算数->"); ss_input(data); printf("英語->"); ss_input(data); } //下記関数で成績をchar型で受け取り、数値化したい。 void ss_input(struct seiseki *data){ char p[100]; int i=0; static int o=0; scanf("%s",p); while( p[i] != '\0'){ if(isdigit(p[i])==0){ printf("再入力してください"); scanf("%s",p); } i++; } data->shu[o]=atof(p); printf("%f\n",data->shu[o]); o++; }

  • C言語のプログラムについて

    このプログラムが作れず困っています。分かる方教えてください。 data.datを入力し構造体型の配列に格納する(データ件数は50件以下,EOFになるまで入力) 次に<CTRL>Dが押されるまで学生番号をキー入力し,その氏名と得点を表示する。 学生番号の探索には二分探索法を使い構造体の配列を調べた回数も表示する。学生番号が存在しない場合は、存在しないことを 示すメッセージを表示する。 [実行例] 学生番号を入力してください ←入力要求のメッセージ(scanfの前に毎回入れる) 1012 1012番Sonoda Mari 得点=42点 探索回数=3回   ←学生番号,氏名,得点,探索回数を表示 学生番号を入力してください 1001 1001番Ando Ichiro 得点=73点  探索回数=1回 学生番号を入力してください 1016 1016番Nakai Kanji 得点=49点 探索回数=2回 学生番号を入力してください 1000 1000番なし 学生番号を入力してください(<CTRL>D=終了) <CTRL>D いちよ私が書いてみたものを載せます。 #include<stdio.h> #include<stdlib.h> int main(void) { struct GDATA { int bango; char sei[11],mei[11]; int tokuten; }; struct GDATA seiseki[50], tmp; int i,lo,hi,flg, kensuu, bango; FILE*fp; if((fp=fopen("data-a.dat","r"))==NULL) { printf("data-a.dat OPEN ERROR!\n"); exit(1); } for(kensuu=0;fscanf(fp,"%d%s%s%d",&tmp.bango, tmp.sei, tmp.mei, &tmp.tokuten)!= EOF;kensuu++) { seiseki[kensuu] = tmp; } printf("学生番号を入力してください\n"); while(scanf("%d", &bango)!= EOF) lo=0; hi=50 flg=0; while(flg==0&&lo<=hi) { i=(lo+hi)/2; if(bango!=seiseki[i].bango) { if(bango<seiseki[i])hi=i-1; elselo=i+1; } else flg=1; } if(flg==1)printf("%d番%s %s 得点=%d点\n",seiseki[i].bango,seiseki[i].sei,seiseki[i].mei,seiseki[i],tokuten); else printf("%d番なし\n",seiseki[i].bango); return 0; }

  • C言語の使い方を教えてください。-C言語入門者

    C言語のプログラムの処理の対象となるファイルはどこに保存したらよいのでしょうか?たとえば下記のプログラムで #include <stdio.h> #include <stdlib.h> #include <string.h> void main(void) { char *line[100], *buf; int i = 0, len, lines; FILE *fp; fp = fopen("textfile.txt", "r"); buf = calloc(128, sizeof(char)); while (i < 100 && fgets(buf, 128, fp) != NULL) { len = strlen(buf); line[i] = calloc(len + 1, sizeof(char)); strcpy(line[i], buf); i++; } fclose(fp); lines = ((i <= 100) ? i :100); free(buf); for(i = 0; i < lines; i++) printf("%s", line[i]); for(i = 0; i < lines; i++) free(line[i]); } で [textfile.txt]という名のファイルをマイドキュメントやコンパイラーを保存しているのと同じ領域に保存してコンパイラーを実行しても所要の結果が得られません。テキストにはプログラムの作り方しか書いてありません。

  • C言語で分からない部分がいくつかあります。

    長文になります。 市のデータ(cities.txt)を対象として、以下の各機能を持ったプログラムを作成しました。 1.情報の登録と一覧表示 2.情報の削除 3.cities.txt からの情報の読み込み 4.citiesDB.txtへのリスト内容の書き出し 5.人口でソート #include <stdio.h> #include <stdlib.h> #include <string.h> #define STRLEN 32 #define BUF_LEN 128 #define CITYDB_R_FILE "cities.txt" // 読み込み用ファイル #define CITYDB_W_FILE "citiesDB.txt" // 書き出し用ファイル struct cities{ char pref[STRLEN]; char city[STRLEN]; int popl; float area; float dens; char founded[STRLEN]; struct cities *next; }; struct cities *root=NULL; // rootへのポインタは大域変数として定義 void *mymalloc(size_t sz){ void *p = (void *)malloc(sz); if(p == NULL){ fprintf(stderr,"ERR: Can't malloc memory %d bytes.",(int)sz); exit(1); } memset(p,0,sz); return p; } void showCity(struct cities *c, FILE *fp){ fprintf(fp,"%s\t%s\t%d\t%.2f\t%.2f\t%s\n", c->pref, c->city, c->popl, c->area, c->dens, c->founded); } struct cities *genNewCityCell(char *pref, char *city, int popl, float area, float dens, char *founded ){ struct cities *c; c = mymalloc(sizeof(struct cities)); // メモリを確保した c に対して、値を代入する return c; } void showList(FILE *fp){ struct cities *cur= root; while(cur != NULL){ showCity(cur,fp); cur = cur->next; } } void saveList(){ // 書き込み用のファイルを開き、そのファイルポインタ fp に対して、 // showList(fp) を呼ぶ。 void showList() は12行上で定義している printf("File saved to %s\n",CITYDB_W_FILE); } struct cities *line2City(char *buf){ struct cities *c=NULL; int popl; char pref[STRLEN], city[STRLEN], founded[STRLEN]; float area, dens; sscanf(buf, "%s %s %d %f %f %s", pref, city, &popl, &area, &dens, founded); c = genNewCityCell(pref,city,popl,area,dens,founded); return c; } void addCity(struct cities *c){ struct cities **cur= &root; /* rootから順にたどって,末尾に挿入する */ } void inputStr(char *buf,int len){ fgets(buf,len,stdin); buf[strlen(buf)-1]='\0'; } void addNewCity(){ char buf[BUF_LEN] = ""; struct cities *c; while(strlen(buf)<=0){ printf("Input one line:\n"); inputStr(buf, BUF_LEN); } if(strncmp(buf, "Prefecture", 10) == 0) return; c = line2City(buf); addCity(c); } void deleteCityFromList(char *delcity){ /* 順にたどり,当該項目を削除する. addCity() も同様. */ } void deleteCity(){ char buf[STRLEN]; showList(stdout); printf("Select Delete City Name:"); inputStr(buf, STRLEN); deleteCityFromList(buf); } void readListFILE(FILE *fp){ char buf[BUF_LEN]; struct cities *c; while( fgets(buf,BUF_LEN,fp) != NULL){ if(strncmp(buf, "Prefecture", 10) == 0) continue; c = line2City(buf); if(c != NULL) addCity(c); } } void readList(){ /* ファイルCITYDB_R_FILEを読み取り用で開く ファイルが開けない場合のエラー処理 readListFILE(fp); ファイルをクローズ */ printf("File loaded\n"); } void insertCityByPopl(struct cities *sc){ struct cities **cur= &root; /* 順にたどり、挿入すべき箇所に sc を挿入 */ } void sortList(){ struct cities *cur,*fr; cur = root; root = NULL; while(cur != NULL){ insertCityByPopl(genNewCityCell(cur->pref, cur->city, cur->popl, cur->area, cur->dens, cur->founded)); fr = cur; cur = cur->next; free(fr); } showList(stdout); } int main(int argc, char *argv[]){ char buf[BUF_LEN]; while(1){ printf("Menu(a:add, d:delete, l:list, s:sort, w:write file, r:read file q:quit):\n"); fgets(buf,BUF_LEN,stdin); switch(buf[0]){ case 'a': addNewCity(); break; case 'd': deleteCity(); break; case 'l': showList(stdout); break; case 's': sortList(); break; case 'w': saveList(); break; case 'r': readList(); break; case 'q': exit(0); break; } } } ただ、コメントのある部分の関数が完成できません・・・・ どなたか教えてください。

  • C言語による構造体の値渡しについて

    以下プログラムを作成しました。 1.read_file関数によりファイルを読み込み。 2.avg_kokugo関数により、国語の平均点を出す。 という流れで組まれているのですが、 1.read_file関数実行時に、dat構造体を渡しています。 2.read_file関数内で、fscanfによる読み込みを行い、dat[i].name,&dat[i].kokugo,&dat[i].sansuに格納しているみたいに感じます。 ここで、疑問なのが、 「構造体を値渡しでdatをread_file関数に渡してる」と思っているのですが、 「read_file関数から、値渡しで渡された構造体datに、値を格納することはできるのでしょうか?」 本を参考にして勉強していたのですが、 「構造体は、値渡しの時に読み込みはできるが、更新はできない」 と書かれていたのです。(ポインタ参照渡しの時は可能。) なぜ今回、read_file関数から、構造体datに値の格納ができるのでしょうか? 更新と新規格納は意味が異なるからなのでしょうか? ご教授よろしくお願いします。 <ソース> #include <stdio.h> //グローバル #define FNAME "test.txt" struct score{ char name[20]; int kokugo; int sansu; }; int read_file(struct score dat[],int n); float avg_kokugo(struct score dat[],int n); int main(void){ struct score dat[3]; int ret; float kokugo; float sansu; ret= read_file(dat,3); if(ret <0){ return 0; } kokugo = avg_kokugo(dat,3); printf("国語の平均 %.1f\n",kokugo); return 0; } int read_file(struct score dat[],int n){ FILE *fp; //ファイルポインタ int i; fp=fopen(FNAME,"r"); if(fp==NULL){ printf("ファイルをオープンできませんでした。\n"); return -1; //-1によるプログラム強制終了 } //データ読み込み i=0; //datに保存していく。 while((fscanf(fp,"%s%d%d",dat[i].name,&dat[i].kokugo,&dat[i].sansu)) != EOF){ i=i+1; //ファイル件数読み込み } fclose(fp); return 0; } float avg_kokugo(struct score dat[],int n){ int sum; //合計 float answer; int i; sum=0; for(i=0;i<n;i++){ sum = sum + dat[i].kokugo; } //平均点を求める answer =(float)sum / (float)n; return answer; }

  • C言語での構造体

    C言語の構造体で配列を扱うとき、 struct ○○{  char ○○[○] とすれば出来ますが、同じようにして構造体で二次元配列を扱うことは出来ますか? 一度組んでみたのですが、 #include<stdio.h> struct aaa{ int no; char name[128]; char y_name[128]; char n_name[128]; char s_name[128][128]; }; int main(void){ int i; struct aaa iryo[99]; printf("入力前\n"); /* 構造体配列に scanf()でデータを入力 */ for(i = 0; i < 3; i++) { // printf("input...\n"); scanf("%d", &iryo[i].no); scanf("%s", iryo[i].name); scanf("%s", iryo[i].y_name); scanf("%s", iryo[i].n_name); scanf("%s", iryo[i].s_name); } printf("入力後\n"); printf("出力前\n"); /* 入力データの確認 */ for(i = 0; i < 3; i++) { printf("番号:%02d 内容:%s Y分岐:%s N分岐:%s 他分岐:%s\n", iryo[i].no, iryo[i].name, iryo[i].y_name, iryo[i].n_name, iryo[i].s_name); } printf("出力後\n"); printf("%d",sizeof(struct aaa)); return 0; } としたら、エラーは出ませんが、実行すると何も表示されませんでした。