<修正後>
#include <stdio.h> #include <string.h> #include <stdlib.h> #define MAX 10 /*--- int 型スタックを実現する構造体 ---*/ typedef struct{ double vision; /* 視力 */ int height; /* 身長 */ } Body ; /*--- 身体検査データ型 ---*/ typedef struct{ Body body; /* 身体データ型 ---*/ char *name; /* 氏名 */ } PhysCheck ; typedef struct { int max; /* スタックの容量 */ int ptr; /* スタックポインタ */ PhysCheck stk[MAX]; /* スタック本体*/ } PhysCheckStack; int Search(PhysCheckStack *s , PhysCheck *x){ int count = 0; for(int i = 0 ; i < s->ptr ; i ++){ if(strcmp(x->name,s->stk[i].name) == 0){//string compare 文字一致したら0返す printf("%s %f %d\n",s->stk[i].name,s->stk[i].body.vision,s->stk[i].body.height); count ++; } } return count; } /*--- スタックの初期化 ---*/ int Initialize(PhysCheckStack *s, int max){ s->ptr = 0; if ((s->stk[s->ptr].name = calloc(max, sizeof(char*))) == NULL) { s->max = 0; /* char* の配列の確保に失敗 */ return -1; } s->max = max; return 0; } /*--- スタックにデータをプッシュ ---*/ int Push(PhysCheckStack *s, PhysCheck *x){ if (s->ptr >= s->max) return -1; /* スタック満杯 */ strcpy(s->stk[s->ptr].name,x->name); if ((s->stk[s->ptr].name = calloc(strlen(x->name)+1, sizeof(char*))) == NULL) /* データをコピーするための動的な文字列保存用配列を確保することに失敗 */ return -1; s->stk[s->ptr].body.vision = x->body.vision; s->stk[s->ptr].body.height = x->body.height; s->ptr++; return 0; } /*--- スタックからデータをポップ ---*/ int Pop(PhysCheckStack *s, PhysCheck *x){ if (s->ptr <= 0) return -1; /* スタックは空 */ s->ptr--; strcpy(x->name,s->stk[s->ptr].name); x->body.vision = s->stk[s->ptr].body.vision; x->body.height = s->stk[s->ptr].body.height; free(s->stk[s->ptr].name); return (0); } /*--- スタックからデータをピーク ---*/ int Peek(PhysCheckStack *s, PhysCheck *x){ if (s->ptr <= 0) return -1; strcpy(x->name,s->stk[s->ptr-1].name); x->body.vision = s->stk[s->ptr-1].body.vision; x->body.height = s->stk[s->ptr-1].body.height; return 0; } /*--- スタックの容量 ---*/ int Capacity(const PhysCheckStack *s){ return s->max; } /*--- スタックに積まれているデータ数 ---*/ int Size(const PhysCheckStack *s){ return s->ptr; } /*--- スタックの全データの表示 ---*/ void Print(const PhysCheckStack *s){ int i; for(i = 0; i < s->ptr; i++) printf("%s %f %d", s->stk[i].name,s->stk[i].body.vision,s->stk[i].body.height); putchar('\n'); } int main(void){ PhysCheckStack s; PhysCheck x; Initialize(&s, MAX); while (1) { int menu; printf("現在のデータ数:%d/%d\n",Size(&s), Capacity(&s)); printf("(1) プッシュ (2) ポップ (3) ピーク (4) 表示 (5) 探索 (0) 終了:"); scanf("%d", &menu); if (menu == 0) break; switch (menu) { case 1: /* プッシュ */ printf("データ:"); scanf("%d", &x.body.height); scanf("%s",x.name); scanf("%lf",&x.body.vision); if (Push(&s, &x) == -1) puts("\a エラー:プッシュに失敗しました。"); break; case 2: /* ポップ */ if (Pop(&s, &x) == -1) puts("\a エラー:ポップに失敗しました。"); else printf("ポップしたデータは%s %.1f %d です。\n", x.name,x.body.vision,x.body.height); break; case 3: /* ピーク */ if (Peek(&s, &x) == -1) puts("\a エラー:ピークに失敗しました。"); else printf("ピークしたデータは%s %.1f %d です。\n", x.name,x.body.vision,x.body.height); break; case 4: /* 表示 */ Print(&s);https://www.onlinegdb.com/fork/HyZW3BAi8#tab-stdin break; case 5://探索 scanf("%s",x.name); int search = Search(&s,&x); if(search == 0){ puts("パターンは存在しません"); } else{ printf("%dパターンあります\n",search); } } } return 0; }
<したいこと>
最初のメニューで1を選択し、push関数に111、aaa、111と入力して、スタックにプッシュします。
メニューで5を選択して、aと入力するとs->ptrが指してる0を返すプログラムを作りたいです。
<現在>
二回プッシュするとSegmentation fault (core dumped) と表示されます。
<質問>
プッシュ、サーチが出来るように実装したいです
char *nameは変えずにコード作成したいです。
<追記>
#include <stdio.h> #include <string.h> #include <stdlib.h> /*--- int 型スタックを実現する構造体 ---*/ typedef struct{ double vision; /* 視力 */ int height; /* 身長 */ } Body ; /*--- 身体検査データ型 ---*/ typedef struct{ Body body; /* 身体データ型 ---*/ char *name; /* 氏名 */ } PhysCheck ; typedef struct { int max; /* スタックの容量 */ int ptr; /* スタックポインタ */ PhysCheck **stk; /* スタック本体*/ } PhysCheckStack; int Search(PhysCheckStack *s , PhysCheck *x){ for(int i = s->ptr-1 ; i >= 0 ; i --){ if(strncmp(s->stk[i]->name, x->name ,strlen(x->name)) == 0){//strncmp先頭n文字を比較 return i; } } return -1; } /*--- スタックの初期化 ---*/ int Initialize(PhysCheckStack *s, int max){ s->ptr = 0; if ((s->stk = calloc(max, sizeof(PhysCheck *))) == NULL) { s->max = 0; /* char* の配列の確保に失敗 */ return -1; } s->max = max; return 0; } /*--- スタックにデータをプッシュ ---*/ int Push(PhysCheckStack *s, PhysCheck *x){ if (s->ptr >= s->max) return -1; /* スタック満杯 */ if ((s->stk[s->ptr] = calloc(strlen(x->name)+1, sizeof(PhysCheck *))) == NULL) /* データをコピーするための動的な文字列保存用配列を確保することに失敗 */ return -1; s->stk[s->ptr]->name = calloc(strlen(x->name)+1, sizeof(char)); strcpy(s->stk[s->ptr]->name,x->name); s->stk[s->ptr]->body.vision = x->body.vision; s->stk[s->ptr]->body.height = x->body.height; s->ptr++; return 0; } /*--- スタックからデータをポップ ---*/ int Pop(PhysCheckStack *s, PhysCheck *x){ if (s->ptr <= 0) return -1; /* スタックは空 */ s->ptr--; strcpy(x->name,s->stk[s->ptr]->name); x->body.vision = s->stk[s->ptr]->body.vision; x->body.height = s->stk[s->ptr]->body.height; free(s->stk[s->ptr]->name); return (0); } /*--- スタックからデータをピーク ---*/ int Peek(PhysCheckStack *s, PhysCheck *x){ if (s->ptr <= 0) return -1; strcpy(x->name,s->stk[s->ptr-1]->name); x->body.vision = s->stk[s->ptr-1]->body.vision; x->body.height = s->stk[s->ptr-1]->body.height; return 0; } /*--- スタックの容量 ---*/ int Capacity(const PhysCheckStack *s){ return s->max; } /*--- スタックに積まれているデータ数 ---*/ int Size(const PhysCheckStack *s){ return s->ptr; } /*--- スタックの全データの表示 ---*/ void Print(const PhysCheckStack *s){ int i; for(i = 0; i < s->ptr; i++) printf("%s %f %d\n", s->stk[i]->name,s->stk[i]->body.vision,s->stk[i]->body.height); putchar('\n'); } void Terminate(PhysCheckStack *s){ if(s->stk != NULL) free(s->stk); s->max = s->ptr = 0; } int main(void){ PhysCheckStack s; PhysCheck x; int max; char y[100]; printf("スタックの大きさを入力してください"); scanf("%d", &max); if (Initialize(&s, max)==-1){ puts("スタックの生成に失敗しました.\n"); } while (1) { int menu; printf("現在のデータ数:%d/%d\n",Size(&s), Capacity(&s)); printf("(1) プッシュ (2) ポップ (3) ピーク (4) 表示 (5) 探索 (0) 終了:"); scanf("%d", &menu); if (menu == 0) break; switch (menu) { case 1: /* プッシュ */ printf("データ:"); scanf("%d", &x.body.height); scanf("%s",y); x.name = (char *)malloc(sizeof(char)*(strlen(y) + 1)); strcpy(x.name,y); scanf("%lf",&x.body.vision); if (Push(&s, &x) == -1) puts("\a エラー:プッシュに失敗しました。"); break; case 2: /* ポップ */ if (Pop(&s, &x) == -1) puts("\a エラー:ポップに失敗しました。"); else printf("ポップしたデータは%s %.1f %d です。\n", x.name,x.body.vision,x.body.height); break; case 3: /* ピーク */ if (Peek(&s, &x) == -1) puts("\a エラー:ピークに失敗しました。"); else printf("ピークしたデータは%s %.1f %d です。\n", x.name,x.body.vision,x.body.height); break; case 4: /* 表示 */ Print(&s); break; case 5://探索 scanf("%s",x.name); int search = Search(&s,&x); if(search == -1){ puts("パターンは存在しません"); } else{ printf("名前に含まれるパターンは%d個です\n",search); } } } return 0; }
自分なりにやってみました。おそらくもっと効率の良いプログラムがあると思っていますが、今の自分でできることはしました。
ポインタについて勉強しなおします。。。
教本ひととおり読んではいかがか?
回答4件
あなたの回答
tips
プレビュー