質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.50%
C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

Q&A

解決済

3回答

4727閲覧

スタックの応用

indehi

総合スコア7

C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

0グッド

0クリップ

投稿2016/05/28 04:23

編集2016/05/28 06:25

スタックを利用して入力された文字列の回文を作るプログラムを作成したら、出力されません。

例えば、「abcd」と入力したら、「abcddcba」と主著力される。
###発生している問題・エラーメッセージ

文字列かendを入力してください->this

文字列かendを入力してください->end

###該当のソースコード

C言語

1#include<stdio.h> 2#include<stdlib.h> 3#include<string.h> 4struct cell{ 5 char c; 6 struct cell *next; 7}; 8 9struct cell *stack,*listhead=NULL; 10char pop(); 11void free_stack(); 12void push(char ic[10]); 13void print_stack(); 14 15int main(void){ 16 char moji[10]; 17 while(1){ 18 printf("文字列かendを入力してください->"); 19 scanf("%s",moji); 20 21 if(strcmp(moji,"end")==0){ 22 free_stack(); 23 return 0; 24 } 25 26 27 else{ 28 while(stack!=NULL){ 29 push(moji); 30 } 31 print_stack(); 32 while(stack!=NULL){ 33 printf("%c",pop()); 34 print_stack(); 35 } 36 37 } 38 } 39} 40 41char pop(){ 42 char popdata; 43 popdata=listhead->c; 44 stack = listhead; 45 listhead = listhead->next; 46 free(stack); 47 return popdata; 48} 49void free_stack(){ 50 if(listhead!=NULL) 51 free(stack); 52} 53void push(char ic[10]){ 54 stack = (struct cell *)malloc(sizeof(struct cell)); 55 stack->c=ic[0]; 56 stack->next =listhead; 57 listhead = stack; 58} 59void print_stack(){ 60 stack = listhead; 61 while(stack!=NULL){ 62 printf("->%c",stack->c); 63 stack = stack->next; 64 } 65 printf("\n"); 66} 67

###試したこと
forループで回す

###補足情報(言語/FW/ツール等のバージョンなど)
より詳細な情報

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

wake_up_kemeko

2016/05/28 05:39

while(stack != NULL) だと、stackがNULLの間は入れないのでpushされずに表示されないのでは?
indehi

2016/05/28 06:31

やりたいことについて編集しました
wake_up_kemeko

2016/05/28 08:26 編集

文字列かendを入力してください->abcd \n abcddcba \n 文字列かendを入力してください-> \n という結果がほしいのでしょうか?
indehi

2016/05/28 08:46

そうです!それです! 配列使った方がいいんでしょうか
HogeAnimalLover

2016/05/28 12:50

固定長配列で良いならその方が作りやすい、可変長への対応は少し高度なので、いきなり試すようなものではないよ。そもそも回文を作るだけならば入力文字列を出力後、逆順に出力すれば良いだけ。練習用の課題としてみるならば可変長の対応の方がずっと高度なので、慣れてからの方が良いよ。
guest

回答3

0

本題に入る前に。

  1. 整形しよう。

せめてインデントは揃えるようにしてください。ソースコードは綺麗に整形しているだけで、読みやすさが断然違います。読みやすければ、動きもわかりやすくなり、どこに問題があるかも把握しやすくなります。ツールなどを用いても良いでしょう。
2. グローバル変数は使わずに、ローカル変数を引数で渡そう。
グローバル変数はです。どうしても使用しなければ実現できない場合を除き、使用すべきではありません。変数は基本的にローカル変数を使いましょう。関数間で使用する変数は引数として渡しましょう。
3. 変数の複数宣言は使わないようにしよう。
int *a, b = 0;と言った変数の複数宣言は混乱の元になりやすく、使用すべきではありません。一つの宣言で一つ変数だけを宣言するようにしてください。
4. マジックナンバーはマクロ定数で定義しよう。
char str[256];としたときの256部分はマジックナンバーと言われます。このマジックナンバーがソースコードの複数箇所に現れると、問題が起きるときがあります。それは、数を変えたときです。全部変更したつもりが変更し忘れがあったりすると、バッファオーバーフローなどの致命的な問題を引き起こします。マクロ定数にして、一括で変更できるようにしましょう。
5. printf()が'\n'で終わらないときは、flushしよう。
C言語の入出力ではバッファリングというものを行っています。ある程度バッファにため込むことで、低速な入出力をなるべく停止しないように行うという仕組みです。printf()も直接標準出力に書き込むのではなく、標準出力のバッファに書き込むに過ぎません。そして、C言語の標準出力のバッファでは、バッファが一杯になるか、改行'\n'が現るまで、出力をしないようになっています。つまり、prinf()が'\n'で終わってなければ、最後まですぐに出力しない場合があります。そういうときはfflush()を使用して、バッファ内容を強制的に出力するように必要があります。
6. scanf()で'%s'のみは危険なので、大きさを指定するか、scanf_s()fegts()を使おう。
scanf("%s", str)とした場合gets()と同じぐらいの危険性をはらんでいます。絶対にこのままにすべきではありません。scanf("%9s", str)scanf_s("%s", str, 10)等とするか、またはfgets()を使いましょう。
7. scanf()等を使用したときは、戻り値チェックとバッファ空読みをしよう。
標準入力が閉じられるなどの理由でscanf()等が失敗するときがあります。必ず戻り値チェックをして、それ以上読み込みできないときは終了するようにしてください。そうでないと無限ループになり、プログラムが暴走するときがあります。また、用意した文字列の長さが足りず、改行まで読み込まれなかった場合もあります。次の読み込みでは読み込まれなかった文がバッファに残っているため、邪魔になります。空読みをして、バッファを空にしてから、次の読み込みを待ちましょう。
8. malloc()の戻り値がNULLでないかをチェックしよう。
メモリが足りないときはmalloc()は失敗し、NULLを返します。そのまま続行してしまうと、アプリケーションが落ちてしまいます。戻り値がNULLでないかをチェックして、失敗した場合は、エラーメッセージなどを出してから、終了するようにしましょう。
9. void hoge()と関数宣言/定義で()内を省略するのはやめよう。
C言語ではvoid hoge()void hoge(void)は意味が異なります。混同してはいけません。()とするのは引数が何でも良いという意味で、古い書き方であり、引数の型チェックがされなくなるためバグの元になります。引数無しであれば、(void)と明示しましょう。

以上を踏まえて、書き換えたら全く別物になってしまいました。ごめんなさい。

C

1#include <stdio.h> 2#include <stdlib.h> 3#include <string.h> 4 5#define MOJI_SIZE 256 6 7struct cell { 8 char c; 9 struct cell *next; 10}; 11 12void push(struct cell **p_stack, char c); 13char pop(struct cell **p_stack); 14struct cell *make_stack(char *str); 15void free_stack(struct cell *stcak); 16void print_stack(struct cell *stack); 17 18int main(void) 19{ 20 while (1) { 21 printf(u8"文字列かendを入力してください->"); 22 fflush(stdout); 23 24 char moji[MOJI_SIZE]; 25 char *result_str = fgets(moji, MOJI_SIZE, stdin); 26 27 if (result_str == NULL) { 28 break; 29 } 30 31 if (moji[strlen(moji) - 1] == '\n') { 32 moji[strlen(moji) - 1] = '\0'; 33 } else { 34 printf(u8"入力文字が多すぎます。\n"); 35 while (1) { 36 int c = getchar(); 37 if (c == EOF || c == '\n') { 38 break; 39 } 40 } 41 continue; 42 } 43 44 if (strcmp(moji, "end") == 0) { 45 break; 46 } 47 48 struct cell *stack = make_stack(moji); 49 struct cell *reverse_stack = NULL; 50 print_stack(stack); 51 while (stack != NULL) { 52 push(&reverse_stack, pop(&stack)); 53 } 54 print_stack(reverse_stack); 55 printf("\n"); 56 free_stack(stack); 57 stack = NULL; 58 free_stack(reverse_stack); 59 reverse_stack = NULL; 60 } 61 return 0; 62} 63 64void push(struct cell **p_stack, char c) 65{ 66 if (*p_stack == NULL) { 67 *p_stack = (struct cell *)malloc(sizeof(struct cell)); 68 if (*p_stack == NULL) { 69 fprintf(stderr, u8"メモリ確保に失敗しました。"); 70 exit(1); 71 } 72 (*p_stack)->c = c; 73 (*p_stack)->next = NULL; 74 return; 75 } 76 push(&((*p_stack)->next), c); 77} 78 79char pop(struct cell **p_stack) 80{ 81 struct cell **p_next = &((*p_stack)->next); 82 if (*p_next == NULL) { 83 char c = (*p_stack)->c; 84 free_stack(*p_stack); 85 *p_stack = NULL; 86 return c; 87 } 88 return pop(p_next); 89} 90 91struct cell *make_stack(char *str) 92{ 93 struct cell *stack = NULL; 94 for (char *p_c = str; *p_c != '\0'; p_c++) { 95 push(&stack, *p_c); 96 } 97 return stack; 98} 99 100void free_stack(struct cell *stack) 101{ 102 if (stack == NULL) 103 return; 104 struct cell *next = stack->next; 105 free(stack); 106 free_stack(next); 107} 108 109void print_stack(struct cell *stack) 110{ 111 if (stack == NULL) { 112 return; 113 } 114 printf("%c", stack->c); 115 print_stack(stack->next); 116}

投稿2016/05/28 08:40

raccy

総合スコア21733

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

やりたいのはこういうことでしょうか?

C

1#include<stdio.h> 2#include<stdlib.h> 3#include<string.h> 4 5#define STRLEN 10 6struct cell { 7 char c[STRLEN]; //文字列を持つなら配列orポインタ 8 struct cell *next; 9}; 10 11struct cell *stack=NULL, *listhead = NULL; 12char pop(); 13void free_stack(); 14void push(char ic[]); 15void print_stack(); 16 17int main(void) { 18 19 20 char moji[STRLEN] = {'\0'}; 21 22 while (1) { 23 printf("文字列かendを入力してください->"); 24 scanf_s("%s", moji,STRLEN);//セキュリティ向上 VSさんが言うこと聞かないので 25 26 if (strcmp(moji, "end") == 0) { 27 free_stack(); 28 return 0; 29 } 30 31 32 else { 33 if (strlen(moji) >= STRLEN) { 34 puts("文字長ながすぎんよ"); 35 continue; 36 } 37 38 push(moji); 39 print_stack(); 40 while (stack != NULL) { 41 printf("%c", pop()); 42 print_stack(); 43 } 44 45 } 46 } 47} 48 49char pop() { 50 char popdata; 51 popdata = listhead->c; 52 stack = listhead; 53 listhead = listhead->next; 54 free(stack); 55 return popdata; 56} 57void free_stack() { 58 if (listhead != NULL) 59 free(stack); 60} 61void push(char ic[]) { 62 stack = (struct cell *)malloc(sizeof(struct cell)); 63 strcpy_s(stack->c,STRLEN,ic);//文字のコピー 64 stack->next = listhead; 65 listhead = stack; 66} 67void print_stack() { 68 stack = listhead; 69 while (stack != NULL) { 70 printf("->%s", stack->c); 71 stack = stack->next; 72 } 73 printf("\n"); 74}

それともこちら?

C

1#include<stdio.h> 2#include<stdlib.h> 3#include<string.h> 4 5#define STRLEN 10 6struct cell { 7 char c; 8 struct cell *next; 9}; 10 11struct cell *stack=NULL, *listhead = NULL; 12char pop(); 13void free_stack(); 14void push(char ic); 15void print_stack(); 16 17int main(void) { 18 19 int i; 20 char moji[STRLEN] = {'\0'}; 21 22 while (1) { 23 printf("文字列かendを入力してください->"); 24 scanf_s("%s", moji,STRLEN);//セキュリティ向上 VSさんが言うこと聞かないので 25 26 if (strcmp(moji, "end") == 0) { 27 free_stack(); 28 return 0; 29 } 30 31 32 else { 33 if (strlen(moji) >= STRLEN) { 34 puts("文字長ながすぎんよ"); 35 continue; 36 } 37 38 for (i = 0; moji[i]; ++i)push(moji[i]);//文字が入力されてるだけ格納 39 40 while (listhead != NULL) {//listheadに変更 41 printf("%c", pop()); 42 print_stack(); 43 } 44 45 } 46 } 47} 48 49char pop() { 50 char popdata; 51 popdata = listhead->c; 52 stack = listhead; 53 listhead = listhead->next; 54 free(stack); 55 return popdata; 56} 57void free_stack() { 58 if (listhead != NULL) 59 free(stack); 60} 61void push(char ic) {//一文字読み込みなら配列じゃなくていい 62 stack = (struct cell *)malloc(sizeof(struct cell)); 63 stack->c = ic; 64 stack->next = listhead; 65 listhead = stack; 66} 67void print_stack() { 68 stack = listhead; 69 while (stack != NULL) { 70 printf("->%c", stack->c); 71 stack = stack->next; 72 } 73 printf("\n"); 74}

投稿2016/05/28 05:49

編集2016/05/28 06:01
wake_up_kemeko

総合スコア104

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

ベストアンサー

こんなのでいいのでしょうか? 質問は随時どうぞ。

C

1#include<stdio.h> 2#include<stdlib.h> 3#include<string.h> 4 5#define STRLEN 10 6struct cell { 7 char c; 8 struct cell *next; 9}; 10 11struct cell *stack = NULL, *listhead = NULL; 12char pop(); 13void free_stack(); 14void push(char ic); 15void print_stack(); 16 17int main(void) { 18 19 int i; 20 char moji[STRLEN] = { '\0' }; 21 22 while (1) { 23 printf("文字列かendを入力してください->"); 24 scanf_s("%s", moji, STRLEN);//セキュリティ向上 VSさんが言うこと聞かないので 25 26 if (strcmp(moji, "end") == 0) { 27 free_stack(); 28 return 0; 29 } 30 31 32 else { 33 if (strlen(moji) >= STRLEN) { 34 puts("文字長ながすぎんよ"); 35 continue; 36 } 37 38 for (i = 0; moji[i]; ++i)push(moji[i]);//文字が入力されてるだけ格納 39 40 while (listhead != NULL) {//listheadに変更 41 printf("%c", pop()); 42 } 43 puts(""); 44 45 } 46 } 47} 48 49char pop() { 50 char popdata; 51 popdata = listhead->c; 52 stack = listhead; 53 listhead = listhead->next; 54 free(stack); 55 return popdata; 56} 57void free_stack() { 58 if (listhead != NULL) 59 free(stack); 60} 61void push(char ic) {//一文字読み込みなら配列じゃなくていい 62 stack = (struct cell *)malloc(sizeof(struct cell)); 63 stack->c = ic; 64 stack->next = listhead; 65 listhead = stack; 66 printf("%c",ic);//挿入される文字を表示 67} 68

投稿2016/05/28 08:35

wake_up_kemeko

総合スコア104

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.50%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問