• ベストアンサー

名簿作成 表示について

名簿作成のプログラム、コンパイルしたときに 自分で入れた名簿を全て表示させたいのですが main関数をどう変えれば出来るでしょうか? このままだと、1人分しか表示されません。 初心者なので丁寧に教えてくださればと思います。 #include<stdio.h> #define NAMELEN 30 #define NOLEN 10 char s; struct gakuseki{ char no[NOLEN]; char name[NAMELEN]; int age; }; struct gakuseki input_data(void){ struct gakuseki st; printf("input student number>"); scanf("%s",&st.no); /*getchar(); fgets(st.no,NOLEN,stdin);*/ printf("input name>"); getchar(); fgets(st.name,NAMELEN,stdin); printf("input age>"); scanf("%d",&st.age); printf("continue?(y/n)"); scanf("%s",&s); return st; }; void output_data(struct gakuseki g){ printf("----------------------------------\n"); printf("student number : %s\n",g.no); printf("name : %s\n",g.name); printf("age : %d\n",g.age); }; int main(){ int i,j; struct gakuseki stud; for(i=0;i<3;i++){ /* struct gakuseki stud;*/ stud=input_data(); if(s=='n') { break; }; }; output_data(stud); };

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

  • ベストアンサー
  • Oh-Orange
  • ベストアンサー率63% (854/1345)
回答No.2

★引数には構造体アドレスを渡す方が良い。 ・回答者 No.1 さんの方法で一通り複数分の入力が出来ます。 ・外部変数 s で『continue?(y/n)』の『n』を入れていますが、  『input_data』関数の戻り値で『yes』、『no』とすればもっと  分かりやすくなりますよ。main 関数が…。 ・また、構造体はアドレス参照させると引数の複写がポインタのみ  だけになり処理の高速化につながります。アドレス参照のときは  『->』というアロー演算で構造体メンバをアクセスします。  『.』はドット演算です。 ●サンプル(回答者 No.1 さんとは別の回答で~す→動作は同じ) int input_data( struct gakuseki *st ) {  char s[ 32 ]; ←ここで宣言(容量に注意)    printf( "input student number>" );  scanf( "%s", &st->no );  /*  getchar();  fgets( st->no, NOLEN, stdin );  */  printf( "input name>" );  getchar();  fgets( st->name, NAMELEN, stdin );  printf( "input age>" );  scanf( "%d", &st->age );  printf( "continue?(y/n)" );  scanf( "%s", s );  return( s[0] ); ←'y' or 'n'を返す } void output_data( struct gakuseki *g ) {  printf( "----------------------------------\n" );  printf( "student number : %s\n", g->no );  printf( "name : %s\n", g->name );  printf( "age : %d\n", g->age ); } int main( void ) {  struct gakuseki stud[ MAXLEN ]; ←人数分の配列  int i, j;    for ( i = 0 ; i < MAXLEN ; i++ ){   if ( input_data(&stud[i]) == 'n' ){    break;   }  }  for ( j = 0 ; j < i ; j++ ){   output_data( &stud[j] );  } } 最後に: ・関数ブロックの最後の『};』にある『;』文字は必要ありません。 ・また、『for』、『if』文にも終わりのブロックに『;』文字が  付いていますが、つける必要はありません。→文法からは『空文』  扱いでエラーにはなりませんが、記述が間違っています。注意。 ・構造体とヘッダ部分は質問者さんの記述どおりです。 ・以上。おわり。

その他の回答 (1)

回答No.1

このプログラムでは、新しくデータを入力するときに、1個前に入力したデータを上書きしてしまうので、最後に入力したデータしか覚えておけません。 今まで入力したデータをすべて格納しておけるように、struct gakusekiの配列を用意し、そこにデータを格納していきます。 #include<stdio.h> #define NAMELEN 30 #define NOLEN 10 char s; #define MAXLEN 100 // データ数の限度 struct gakuseki{ char no[NOLEN]; char name[NAMELEN]; int age; }; struct gakuseki input_data(void){ struct gakuseki st; printf("input student number>"); scanf("%s",&st.no); /*getchar(); fgets(st.no,NOLEN,stdin);*/ printf("input name>"); getchar(); fgets(st.name,NAMELEN,stdin); printf("input age>"); scanf("%d",&st.age); printf("continue?(y/n)"); scanf("%s",&s); return st; }; void output_data(struct gakuseki g){ printf("----------------------------------\n"); printf("student number : %s\n",g.no); printf("name : %s\n",g.name); printf("age : %d\n",g.age); } int main(){ int i,j; /* 配列を用意 */ struct gakuseki stud[MAXLEN]; /* ループはデータ数限度まで */ for(i=0;i<MAXLEN;i++){ stud[i]=input_data(); if(s=='n'){ break; } } /* この時点で i は (入力したデータ数-1) となっている */ /* 入力したすべてのデータを出力する */ for(j=0;j<=i;++j) output_data(stud[j]); return 0; }

torya9
質問者

お礼

ありがとうございます。 うまく作れました。 感謝です。

関連するQ&A

  • 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; } としたら、エラーは出ませんが、実行すると何も表示されませんでした。

  • 配列の中を変更

    入力したnameに、入力したageの数だけ文字を進める(例えばnameがOda、ageが12→表示結果がAmp)にする関数を作成しようとしたのですが、やり方がまったくわかりません。 そもそもこのような場合、文字1つ1つに別の配列を使わなければならないのでしょうか? #include <stdio.h> #define N 1 #define NAME 20 typedef struct{ char name[NAME]; char age; } person; int main(void){ int i; person persons[N]; for(i=0;i<N;i++){ printf("name > "); scanf("%s" , persons[i].name); printf("age > "); scanf("%d" , &persons[i].age); } for(i=0;i<N;i++){ printf("name = %s\n" , persons[i].name); printf("age = %d\n" , persons[i].age); } return 0; }

  • 構造体の構造体 引数

    構造体の中の構造体の関数の引き渡し方法がわかりません。 下記ソースで試したのですが、うまくいきませんでした。 助言お願いいたします。 //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++; }

  • scanfの\nの意味

    タイトルの通りです。 #include<stdio.h> struct Person{ char name[100]; char gender; int age; }; int main(void) { struct Person person1; printf("名前は:"); scanf("%s",person1.name); printf("\n年齢は:"); scanf("%d",&person1.age); printf("\n性別は:"); scanf("\n%c",&person1.gender); printf("\n{name=%s,age=%d,gender=%c}",person1.name,person1.age,person1.gender); return 0; } 上記において aaa , 11 , M と入力すると {name=aaa,age=11,gender=M} と表示されますが、 scanf("\n%c",&person1.gender); を scanf("%c",&person1.gender); に変えると {name=aaa,age=11,gender= } となってしまいます。 この理由と、/nの意味を教えてください。

  • プログラミング構造体について。

    include<stdio.h> #include<stdlib.h> #include<string.h> struct person{ char name[10]; int gender; int age; }; void printPersonList(struct person *person_p, int size); void outputPersonList(struct person *person_p, int size); double getAverageOfAge(struct person *person_p, int size); int countMales(struct person *person_p, int size); int countFemales(struct person *person_p, int size); int main(void){ struct person *person_p; int i, count, gender, age, maleCount, femaleCount; char name[20]; double average; printf("登録する人数を入力してください。\n"); scanf("%d", &count); person_p = (struct person*)malloc(sizeof(struct person)* count); for(i=0; i < count; i++){ printf("名前・性別(男性:0, 女性:1)・年齢をスペース区切りで入力してください。\n"); scanf("%s %d %d", name, &gender, &age); strcpy((person_p + i) -> name, name); (person_p + i) -> gender = gender; (person_p + i) -> age = age; } printPersonList(person_p, count); outputPersonList(person_p, count); average = getAverageOfAge(person_p, count); printf("平均年齢:%f\n", average); maleCount = countMales(person_p, count); femaleCount = countFemales(person_p, count); printf("男性:%d名, 女性:%d名\n", maleCount, femaleCount); free(person_p); return 1; } void printPersonList(struct person *person_p, int size){ int i; printf("登録リスト\n"); printf(" name | gender | age\n"); printf("----------+--------+-----\n"); for(i=0; i < size; i++){ printf("%10s | %1d | %2d\n", (person_p + i) -> name, (person_p + i) -> gender, (person_p + i) -> age); } } void outputPersonList(struct person *person_p, int size){ FILE *output; int i; if((output = fopen("meibo.c", "w")) == NULL){ printf("meibo.cを開けませんでした。\n"); return; } for(i=0; i < size; i++){ fprintf(output, "%s, %d, %d\n", (person_p + i) -> name, (person_p + i) -> gender, (person_p + i) -> age); } fclose(output); } 残り3つの関数をすべて定義する(それぞれ10行程度) getAverageOfAge, countMales, countFemales どう定義すればいいのか教えてください。お願いします。

  • CTR-Dでプログラムを終了

    学校の課題で、 --- 探索キーとして名前を入力し、入力と一致した場合、その名前と年齢を印字することを繰り返す。 CTR-Dが入力されたとき、プログラムを終了する。 また、文字比較の為に関数strcmpを使用する。 --- という課題が出されたのですが、while(scanf("%s", name) != EOF)を入れるとうまくいきません。 自分で途中までやったものは↓のものです。 どこが違うのか教えてください(>_<) #include<stdio.h> #include<string.h> #define N 10 struct card{ char *name; int age; }; struct card meibo[N] = { "Takahashi", 14, "Kobayashi", 15, "Hosokawa", 17, "Sugimoto", 18, "Sawai", 19, "Itou", 20, "Kawai", 22, "Ishikura", 24, "Oda", 25, "Nakamura", 28 }; int main(void){ char *name; int i; printf("name? : "); scanf("%s", name); while (scanf("%s", name) != EOF){ for (i=0; i<N; i++){ if (strcmp(name, meibo[i].name) == 0) break; } } if (i<N){ printf("%s is %d.\n", meibo[i].name, meibo[i].age);} else{ printf("Not found.\n");} return 0; }

  • 関数への構造体の配列の渡し方<c言語初心者>

    こんにちは、関数への構造体の配列の渡し方で理解できない点があるため、質問させていただきます。 以下がスクリプトになります。3人の名前と年齢をinput関数で入力し、それらのデータをoutput関数で出力するのが目的です。 #include <stdio.h> typedef struct{ char name[64]; int age; }property; void input(property *data[]); void output(property *data[]); int main(void){ property data[3]; printf("Input data of three people.\n"); input(&data); output(&data); return 0; } void input(property *data[]){ int i; for(i=0;i<3;i++){ printf("%d banme\n",i+1); printf("name:"); scanf("%s",&data[i]->name); printf(" age:"); scanf("%3d",&data[i]->age); } return; } void output(property *data[]){ int i; for(i=0;i<3;i++){ printf("%d banme\n",i+1); printf("name:%s\n",data[i]->name); printf("age :%3d\n",data[i]->age); } return; } コンパイル時のエラーメッセージは以下のようになりました。(ファイル名はstructure5.c) structure5.c: In function ‘main’: structure5.c:14:2: warning: passing argument 1 of ‘input’ from incompatible pointer type [enabled by default] input(&data); ^ structure5.c:8:6: note: expected ‘struct property **’ but argument is of type ‘struct property (*)[3]’ void input(property *data[]); ^ structure5.c:15:2: warning: passing argument 1 of ‘output’ from incompatible pointer type [enabled by default] output(&data); ^ structure5.c:9:6: note: expected ‘struct property **’ but argument is of type ‘struct property (*)[3]’ void output(property *data[]); ^ structure5.c: In function ‘input’: structure5.c:24:3: warning: format ‘%s’ expects argument of type ‘char *’, but argument 2 has type ‘char (*)[64]’ [-Wformat=] scanf("%s",&data[i]->name); ^ 構造体の配列をinput関数やoutput関数に渡すときにエラーが発生しているようなのですが、自分で調べても解決できなかったため、質問させて頂きます。 皆様のお知恵を貸してください。なおプログラミング言語自体初心者のため、できる限りわかりやすいお言葉でご教授願います。よろしくお願い致します。

  • コンパイルエラーの原因が解らず困っています。

    構造体に自作関数から値を入力したいのですが、エラーがでて詰まっています。コンパイルエラーの原因は●の行で signed char * 型として定義されているので int は渡せない と表示されました。 何故このエラーが表示されるのか、また対処法を教えて下さると幸いです。。 #include<stdio.h> #include<string.h> typedef struct { char l_name[256]; int l_age; int l_height; }HUMAN; Input (HUMAN*); main() { HUMAN *l_phuman; Input(l_phuman); } Input(HUMAN* l_phuman) { char names[20]; int ages; int heights; printf("名前を入力してください\n"); scanf("%s" , names); printf("歳を入力してください\n"); scanf("%d" , &ages); printf("歳を入力してください\n"); scanf("%d" , &heights); ●strcpy(*l_phuman->l_name,names); l_phuman->l_age=ages; l_phuman->l_height=heights; printf("%s" , l_phuman->l_name); printf("%d" , l_phuman->l_age); printf("%d" , l_phuman->l_height); } 尚指示としてHUMAN *l_phumanを使って構造体に入れなければなりません。。

  • プログラミングの質問です

    #include<stdio.h> #include<stdlib.h> #include<string.h> struct person{ char name[10]; int gender; int age; }; void printPersonList(struct person *person_p, int size); void outputPersonList(struct person *person_p, int size); double getAverageOfAge(struct person *person_p, int size); int countMales(struct person *person_p, int size); int countFemales(struct person *person_p, int size); int main(void){ struct person *person_p; int i, count, gender, age, maleCount, femaleCount; char name[20]; double average; printf("登録する人数を入力してください。\n"); scanf("%d", &count); person_p = (struct person*)malloc(sizeof(struct person)* count); for(i=0; i < count; i++){ printf("名前・性別(男性:0, 女性:1)・年齢をスペース区切りで入力してください。\n"); scanf("%s %d %d", name, &gender, &age); strcpy((person_p + i) -> name, name); (person_p + i) -> gender = gender; (person_p + i) -> age = age; } printPersonList(person_p, count); outputPersonList(person_p, count); average = getAverageOfAge(person_p, count); printf("平均年齢:%f\n", average); maleCount = countMales(person_p, count); femaleCount = countFemales(person_p, count); printf("男性:%d名, 女性:%d名\n", maleCount, femaleCount); free(person_p); return 1; } void printPersonList(struct person *person_p, int size){ int i; printf("登録リスト\n"); printf(" name | gender | age\n"); printf("----------+--------+-----\n"); for(i=0; i < size; i++){ printf("%10s | %1d | %2d\n", (person_p + i) -> name, (person_p + i) -> gender, (person_p + i) -> age); } } void outputPersonList(struct person *person_p, int size){ FILE *output; int i; if((output = fopen("meibo.c", "w")) == NULL){ printf("meibo.cを開けませんでした。\n"); return; } for(i=0; i < size; i++){ fprintf(output, "%s, %d, %d\n", (person_p + i) -> name, (person_p + i) -> gender, (person_p + i) -> age); } fclose(output); } 上は、「キーボードで入力した個人データ(名前、性別、年齢)を構造体に入れて、一覧を画面に出し、かつ、ファイルに書き出す」ことをするプログラムです。これを名前が辞書順になるようにしたいです。どう書くのか教えてください。

  • C言語について

    #include <stdio.h> struct syoukai{ int no; char name[5]; }; int main(void) { struct syoukai mine = {3, "aaaaa"}; int cmdID ; printf("コマンドを入力してください\n"); scanf("%d\n",cmdID); if(cmdID == 1) printf("%d\n",syoukai.no, syoukai.name); } これをコンパイルして実行すると Segmentation fault とエラーになってしまい原因がわかりません 教えていただけますか?

専門家に質問してみよう