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

このQ&Aのポイント
  • プログラミング構造体とは、C言語で使用されるデータ構造の一種です。構造体は複数の異なる型を持つメンバー変数をひとまとめにして扱うことができます。
  • プログラミング構造体を使用することで、関連する変数をまとめて扱ったり、複数の値を返すことができます。また、構造体を配列として使用することもできます。
  • プログラミング構造体を使用することで、データの構造を明確に表現することができます。また、関数の引数として構造体を渡したり、構造体を返す関数を定義することもできます。
回答を見る
  • ベストアンサー

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

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 どう定義すればいいのか教えてください。お願いします。

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

  • ベストアンサー
  • D-Matsu
  • ベストアンサー率45% (1080/2394)
回答No.2

・メンバーgenderはintよりenumの方がいい。あるいはMALE、FEMALEという定数定義をdefineする手もある ・動的配列ではなく線形リスト構造なら関数にサイズを渡す必要がなくなり、不正サイズによるメモリアクセスエラーの可能性も配列アクセスよりは低くなる。もっとも今回なら全部に入力値を使うだけなのであまり違いはないとも言える という「そもそもの部分」は書くだけ書いておいて。 printPersonList、outputPersonListで「入力データの最初から最後までアクセスする」部分は出ています。 AverageOfAge、つまり「年齢の平均」は「全ての入力データの合計/人数」です。 countMale/Femaleは男女それぞれの人数、つまりgenderの値が男(女)を示す要素の総数です。 これだけ書けばここまでプログラムが書けている人なら普通はわかると思いますが、わからなければ「どこがわからないのか」を明確にした上で補足してください。 なお「全部わからない」というのは「自分で考える気がない」というのと同義なので無視します。あしからず。

bewitch66
質問者

補足

回答ありがとうございます。 とりあえず書いてみたんですけど、printfのところはどぅやってかけばいいのかよくわからなかったんですが、以下のような書き方は間違ってますか?あと、もし男性なら0を数える、女性なら1を数えるやり方なんですが、gender++はダメですよね? double getAverageOfAge(struct person *person_p, int size){ int i, count, sum, average, age; sum = sum + age; average = sum / count; for(i=0; i < size; i++){ printf("%f, &average\n", (person_p + i) -> name, (person_p + i) -> gender, (person_p + i) -> age); } } int countMales(struct person *person_p, int size){ int i, gender; if(gender == 0){ pintf("gender++\n", (person_p + i) -> name, (person_p + i) -> gender, (person_p + i) -> age); } } } int countFemales(struct person *person_p, int size){ int i, gender; if(gender == 1){ printf("gender++\n", (person_p + i) -> name, (person_p + i) -> gender, (person_p + i) -> age); } } }

その他の回答 (1)

  • SaKaKashi
  • ベストアンサー率24% (755/3136)
回答No.1

それらの関数が何をどうするのかさっぱりわかりませんけど。 例えば、言葉の違う国のレストランに入って、日本語で「ただ腹減った」とだけしか言わないのと全く同じです。 想像はできますけど、プログラムは想像ではできませんので。 まず問題なのは、 >strcpy((person_p + i) -> name, name); 構造体のnameのサイズを無視してコピーしてます。典型的なメモリ破壊と脆弱性と言う弱点です。

関連するQ&A

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

    #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); } 上は、「キーボードで入力した個人データ(名前、性別、年齢)を構造体に入れて、一覧を画面に出し、かつ、ファイルに書き出す」ことをするプログラムです。これを名前が辞書順になるようにしたいです。どう書くのか教えてください。

  • 構造体について

    5件のデータをRECORDに追加したいのですが、 RECORD inputdata(void)の宣言文エラーなどのコンパイルエラー。それと、inputdataを用いてどうやって5件のデータを入れたらいいかがわかりません。教えてください。 #define SIZE 5 #include <stdio.h> typedef struct{ int yy; int mm; int dd; }YMD; typedef struct{ char name[20]; YMD birthday; int age; }RECORD; RECORD inputdata(void); void main(void) { int i; for(i = 0;i < SIZE;i++){ inputdata(); } RECORD inputdata(void) { RECORD person; printf("名前>"); scanf("%s", person.name); printf("誕生日入力\n"); printf("年>"); scanf("%d", person.birthday.yy); printf("月>"); scanf("%d", person.birthday.mm); printf("日>"); scanf("%d", person.birthday.dd); return person; }

  • 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の意味を教えてください。

  • 構造体の構造体 引数

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

  • リストの削除について(構造体)

    リストの削除のプログラムを実行して行ってみると、リストの削除処理中にプログラムが終わって変更後処理がうまく表示されません。どこが間違っているかが分からないしだいです。返答のほどよろしくお願いいたします。 #include<stdio.h> #include<malloc.h> #include<string.h> struct list{ char name[20]; int age; struct list *next; }; void main(void) { struct list *head, *p, *n, *old; char key[20]; /*ダミーノード作成*/ head = (struct list*)malloc(sizeof(struct list)); old = head; while(p = (struct list*)malloc(sizeof(struct list)), printf("name age入力\n"), scanf("%s %d", p -> name, &p -> age) != EOF){ old -> next = p; old = p; } free(p); old -> next = NULL; p = head -> next; printf("変更前リスト\n"); while(p != NULL){ printf("name:%s age:%d\n",p -> name, p -> age); p = p -> next; } printf("削除key入力(name)\n"); gets(key); n = head; while(n != NULL){ old = n; n = n -> next; //printf("n -> name %s\n", n -> name); if(strcmp(n -> name, key) == 0){ printf("%s削除\n", key); //printf("n -> name %s old -> name %s\n", n -> name, old -> name); old -> next = n -> next; } } p = head -> next; printf("変更後リスト\n"); while(p != NULL){ printf("name:%s age:%d\n", p -> name, p -> age); p = p -> next; } }

  • 構造体配列

    いつもお世話になっています。 今日構造体配列を勉強した際に下の演習をしていたのですが、いまいち基礎的な関数や配列のことやコマンドライン引数のことが理解できていません。一応自分なりにプログラムを書いてみたのですが、エラーがでます。 どなたかアドバイス・ご指摘・解説・例などをおねがいいたします。 問題はコマンドライン引数で人数を指定し,人数分のデータを標準入力(キーボード)から構造体配列に入力し,標準出力(ディスプレイ)に出力するプログラムです。 #include<stdio.h> typedef struct{ char name[100]; int age; double height; double weight; } PERSONAL_DATA1; typedef struct{ int person[10]; }PERSONAL_DATA2; PERSONAL_DATA1 input_personal_data(int num); void output_personal_data(PERSONAL_DATA2 person[10],int num); int main(int argc, char *argv[]){ PERSONAL_DATA1 x; int num,i; char person[10]; if(argc != 2){ printf("Usage ./test number"); return 0; } num=atoi(argv[1]); for(i=0;i<10&&i<num;i++){ person[i]=input_personal_data(); output_personal_data(person,num); return 0; } } PERSONAL_DATA input_personal_data(void){ PERSONAL_DATA1 x; printf("name>"); scanf("%c" ,&x.name); printf("age>"); scanf("%d" ,&x.age); printf("height>"); scanf("%lf" ,&x.height); printf("weight>"); scanf("%lf" ,&x.weight); return x; } void output_personal_data(PERSONAL_DATA2 person[10],int num){ PERSONAL_DATA1 x; printf("name>>%s\n" ,x.name); printf("age>>%d\n" ,x.age); printf("height>>%lf[cm]\n" ,x.height); printf("weight>>%lf[kg]\n" ,x.weight); } またコマンドライン引数で指定したデータファイルAから入力した個人データ集合を構造体配列に取り込み,標準出力(ディスプレイ)と同じくコマンドライン引数で指定したデータファイルBへファイル出力に出力するプログラムというおまけの問題もあります。 こちらの問題のヒントもいただけませんか?

  • 構造体についてです。

    身体測定表を作っていて最初に作ったデータを変更して表示したいのですがNo1の168cm→162cm No2の74kg→74.5kg  No3の20歳→19歳 No4の田中三郎→小林三郎 (No3と4は構造体ポインタを使ってデータを変更) 全データを表示させてその後No1と3の名前~体重を丸ごと入れ替えて全データを表示させたいのですがエラーがでてしまいます。 分かる人がいましたらどこを直したらいいか教えて下さい。 #include <stdio.h> #include <string.h> struct data{ int no; char name[21]; int age; int height; float weight; }; struct data *sp; void main(){ int i; struct data a[4]={ {1,"鈴木太郎",23,168,60}, {2,"山本次郎",17,180,74}, {3,"山田花子",20,156,53}, {4,"田中三郎",35,172,68}, }; struct data b; for(i=0;i<4;i++){ printf("番号 :%d\n",a[i].no); printf("名前 :%s\n",a[i].name); printf("年齢 :%d歳\n",a[i].age); printf("身長 :%dcm\n",a[i].height); printf("体重 :%4.1fkg\n\n",a[i]. weight); } a[0].height=162; a[1].weight=74.5; *sp[2].age=19; strcpy(*sp[3].name,"小林三郎"); for(i=0;i<=4;i++){ b=a[0]; a[0]=a[2]; a[2]=b; a[0].no=1; a[2].no=3; } for(i=0;i<=4;i++){ printf("番号 :%d\n",a[i].no); printf("名前 :%s\n",a[i].name); printf("年齢 :%d歳\n",a[i].age); printf("身長 :%dcm\n",a[i].height); printf("体重 :%4.1fkg\n\n",a[i].weight); } }

  • 関数への構造体の配列の渡し方<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関数に渡すときにエラーが発生しているようなのですが、自分で調べても解決できなかったため、質問させて頂きます。 皆様のお知恵を貸してください。なおプログラミング言語自体初心者のため、できる限りわかりやすいお言葉でご教授願います。よろしくお願い致します。

  • C言語 「構造体のソートと結果のファイル出力」 緊急です。助けてください。

    授業で課題が出され内容は以下となってます。 1.歴代アメリカ大統領の情報を構造体とする. 2.ソートを昇順で行うこと 3.結果を出力すること〔参考:http://www-it.sci.waseda.ac.jp/CPR1/class08/kekka.log) 以下が自分で作ってみたものですが、多数のエラーが出てしまいどうしたらいいのか分かりません。。。抜本的な変更でもかまいませんので、分かる方助けてください。 -----作成分------ #include <stdio.h> #include <string.h> struct president { int no, age; char name1[20], name2[20]; /* 氏名 */ }; int main(void) { int i; struct president pre1[44] = { {1,57,"George","Washington"}, {2,61,"John","Adams"}, {3,57,"Thomas","Jefferson"}, //リストが長いので省略// {44,47,"Barack","Obama"}, }; struct president *pres; pres = pre1; //ポインタ// sort(pres, 44, sizeof(struct president), president_cmp);//ソート構文 エラーがでます。。。// printf("---------sortted list by age------- \n # age first last \n");} for (i = 0; i < 44; i++){printf("------------------------------------ \n") printf("%d %d %s %s \n, pres[i]->no, pres[i]->name, pres[i]->name1, pres[i]->name2);} for(i = 0; i < 44; i++) { if (i==0){printf("---------list of presidents---------- \n");//RAW DATAの表示を行ない。ここは問題ないみたいです// printf(" age first last \n");}; printf("%d %d %s %s \n", pres->no, pres->age, pres->name1, pres->name2); ++pres; } return 0; } int president_cmp(const void*p1, const void*p2){ //比較関数// struct president *cmp1 = (struct president*)p1; struct president *cmp2 = (struct president*)p2; return strcmp(cmp1->age, cmp2->age); } ここにファイル出力の分をたしたいのですが、どこにどうすればいいのでしょう。 大変申し訳ありませんが、緊急です!!お願いします。

  • C言語 家系図

    問題 構造体personを以下のように仮定する。 struct person { int age; char name[20]; struct person *father; struct person *mother; }; この構造体の表す人の名前、年齢、その人の父親の名前、およびその人の母親の名前を出力する関数 void print_person(struct person *p) を作成せよ。出力の形式は name: 本人の名前 age: 本人の年齢 father: 父親の名前 mother: 母親の名前 となるようにすること。 また、ポインタ father や mother の値が NULL のときには、名前のかわりに unknown と出力するようにせよ。 以上が問題なのですが自分でプログラムを作ってみたところ実行したら、エラーになって矯正終了されてしまいました。 以下が私の作ったプログラムです。 #include <stdio.h> struct person { int age; char name[20]; struct person *father; struct person *mother; }; void set_name(struct person *p, char name[]) { int i; i = 0; while (name[i] != 0) { p->name[i] = name[i]; i++; } p->name[i] = 0; } void print_person(struct person *p) { printf("name:%s", p->name); printf("age:%s\n",p->age); if(p->father != NULL){ printf("father:%s\n",p->father); } else{ printf("unknown"); } if(p->mother != NULL){ printf("mother:%s\n",p->mother); } else{ printf("unknown"); } } int main(void) { struct person me, dad, mom; set_name(&me, "Michael"); me.age = 16; me.father = &dad; me.mother = &mom; set_name(&dad, "David"); dad.age = 38; dad.father = NULL; dad.mother = NULL; set_name(&mom, "Susan"); mom.age = 36; mom.father = NULL; mom.mother = NULL; print_person(&me); print_person(&dad); print_person(&mom); return (0); } どこが違うのか教えていただけないでしょうか?