• ベストアンサー

プログラムについて

今スタっクのファイルから読み込んだ文字列をスタっクへプっシュしたりポっプしたりする過程がわかるプログラムを作ってます 。 作りかけのプログラムですがどこをどうすればいいか教えてください!! 一応コンパイルできます。 使ってない関数があるかもしれません。 #include <stdio.h> #include <stdlib.h> #include <string.h> #define NUMBER 100 /*--- スタックを実現する構造体 ---*/ typedef struct { int max; /* スタックのサイズ */ int ptr; /* スタックポインタ */ char *stk; /* スタック(の先頭要素へのポインタ) */ } Stack; /*--- スタックの初期化 ---*/ int StackAlloc(Stack *s, int max) { s->ptr = 0; if ((s->stk = calloc(max, sizeof(int))) == NULL) { s->max = 0; /* 配列の確保に失敗 */ return (-1); } s->max = max; return (0); } /*--- スタックの後始末 ---*/ void StackFree(Stack *s) { if (s->stk != NULL) { free(s->stk); s->max = s->ptr = 0; } } /*--- スタックにデータをプッシュ ---*/ int StackPush(Stack *s, int x, int i,char *a[]) { if (s->ptr >= s->max) return (-1); if(x>=i) { puts("プッシュできる文字データはありません。"); return (-1); } strcpy(&s->stk[s->ptr++],&(*a)[x]); x++; return x; } /*--- スタックからデータをポップ ---*/ int StackPop(Stack *s, int x,char *a[]) { if (s->ptr <= 0) /* スタックは空 */ return (-1); strcpy(&s->stk[--s->ptr],&(*a)[x]); return (0); } /*--- スタックからデータをピーク ---*/ int StackPeek(const Stack *s, int *x) { if (s->ptr <= 0) /* スタックは空 */ return (-1); *x = s->stk[s->ptr - 1]; return (0); } /*--- スタックの大きさ ---*/ int StackSize(const Stack *s) { return (s->max); } /*--- スタックに積まれているデータ数 ---*/ int StackNo(const Stack *s) { return (s->ptr); } /*--- スタックは空か ---*/ int StackIsEmpty(const Stack *s) { return (s->ptr <= 0); } /*--- スタックは満杯か ---*/ int StackIsFull(const Stack *s) { return (s->ptr >= s->max); } /*--- スタックを空にする ---*/ void StackClear(Stack *s) { s->ptr = 0; } int main(void) { int i=0,j,ret,x=0; char *a[NUMBER]; char buffer[20]; FILE *fpin; Stack s; fpin=fopen("input2.txt","r"); //テキストファイルを読み取りモードで開く while(fgets(&buffer[0],sizeof(buffer),fpin) !=NULL ) { if(i>=NUMBER)//読み込む人数がNUMBERを超えてる時の処理 { puts("人数が100人を超えています"); goto END; } strcpy(&a[i][0],&buffer[0]); /*ret=sscanf(&buffer[0],"%s",&a[i][0]); //データ文字列を3分割 if(ret!=1) //1に分割できなかったときの処理 { puts("代入された入力項目の個数が3でありません"); goto END; }*/ i++; } for(j=0; j<i; j++) printf("%s\n",&(*a)[j]); if (StackAlloc(&s, 100) == -1) { puts("スタックの確保に失敗しました。"); return (1); } while (1) { int m; printf("現在のデータ数:%d/%d\n", StackNo(&s), StackSize(&s)); printf("(1) プッシュ (2) ポップ (0) 終了:"); scanf("%d", &m); if (m == 0) break; switch (m) { case 1: printf("データ:"); puts("こんちくしょ~"); if(StackPush(&s, x,i,&(*a)) == -1) puts("スタックへのプッシュに失敗しました。"); break; case 2: if(StackPop(&s, x,&(*a)) == -1) puts("ポップできません。"); else printf("ポップしたデータは%sです。\n", &s.stk[s.ptr]); break; } } StackFree(&s); END: fclose(fpin); return (0); }

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

  • ベストアンサー
  • plh
  • ベストアンサー率50% (4/8)
回答No.2

端的に答えるならば、 「まずはStackPush(Stack *s, int x, int i,char *a[])の*a[]の渡し方はあってるのか?」--->否 「if(StackPop(&s, x,&(*a)) == -1)の&(*a)のところは適切かという点です。」--->否 ですね。 ガッツのあるコードではありますが、まず main の冒頭の char *a[NUMBER]; がダメですね。 これは、NUMBER 個の文字列の入れ物を確保しようとしているのであろうと想像されますが、char *a[NUMBER]; は NUMBER 個のポインタが確保されるだけなので、strcpy(&a[i][0],&buffer[0]); の実行でアウトになります。 sizeof a; で a として確保されたメモリの量が分かりますから、何バイトのメモリが確保されたのか確認してみてください。 この意味が分からないならばまずは、スタックというよりも、ポインタや配列について学んでください。 多分、二つの選択肢があると思います。 1. 配列やポインタをもう少し理解してからスタックに取り組むようにする。 2. あくまでスタックにこだわるのであれば、calloc() でメモリを確保しない方法に切り替える。これは、スタック自体を例えば次のように配列にすれば可能です。 char Stack[MAX_STACK_DEPTH][MAX_STRING_LENGTH]; 健闘を祈ります。

hiro3932
質問者

お礼

ありがとうございました。 おかげで完成できました。

その他の回答 (1)

  • arain
  • ベストアンサー率27% (292/1049)
回答No.1

>作りかけのプログラムですがどこをどうすればいいか教えてください!! とりあえず確認したいのですが、質問内容は 何か不具合か何かあることについての質問ですか? それとも、不具合以外の内容ですか? であれば何を聞きたいのか教えてください 上記の説明がなく、長文のソースを読んで理解しろというのはどれだけ大変なことか、プログラムを組めるのなら理解できますよね? 個人的に気になったこと ・「goto」は処理抜けが発生しやすいので使用しない方がいい ・switch()文にはdefaultを付ける

hiro3932
質問者

お礼

回答ありがとうございます。 確かに分かりにくいですね。すみませんでした。 補足します。 まずはStackPush(Stack *s, int x, int i,char *a[])の*a[]の渡し方はあってるのか? if(StackPop(&s, x,&(*a)) == -1)の&(*a)のところは適切かという点です。 すみません。言葉で説明するの苦手で。

関連するQ&A