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

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

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

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

Q&A

解決済

2回答

4770閲覧

スタックを使った()と{}の対象関係を調べるプログラムを作成中です・・・・

KSKS

総合スコア7

C

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

0グッド

0クリップ

投稿2016/09/16 11:04

###ファイルを読み込み、スタックを用いて()と{}のそれぞれについて対応関係が問題ないかを調べるプログラムを作りたいです

学校で先日、新しくスタックを学んだので、実際に自分で作ってみようと思いプログラムを書いてみたのですがなかなか上手くいきません。

###発生している問題・エラーメッセージ
()の数があっていても「カッコについて間違いがあります」と出てしまいます。
()と{}について調べたいのですが '(' || '{' という条件の書き方があっているのかわかりません。
popという関数で取り出しをしているはずなのにきちんと取り出せていないようです。

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

C

1#include <stdio.h> 2#include <stdlib.h> 3#define true 1 4#define false (!true) 5#define STACKSIZE 20 6//typedef int bool; 7#define bool int 8 9bool push(int data); 10int pop(void); 11int peek(void); 12bool is_full(void); 13bool is_empty(void); 14void print_stack(void); 15 16int stack[STACKSIZE]; 17int top=0; 18 19int main(void) 20{ 21 22 FILE *fp; 23 char fname[] = "text.txt"; 24 char ch; 25 26 fp = fopen(fname,"r"); 27 if(fp == NULL){ 28 fprintf(stderr,"Can't open %s.\n",fname); 29 return EXIT_FAILURE; 30 }else{ 31 while((ch=fgetc(fp)) != EOF){ 32 if(ch ==( '(' || '{') ){ 33 push(10); 34 } 35 else if(ch==( ')' || '}' )){ 36 pop(); 37 } 38 } 39 40 printf("\n"); 41 fclose(fp); 42 } 43 44 if(stack[top]==10 45 printf("カッコについて間違いがあります。\n"); 46 }else { 47 printf("問題はありません。\n"); 48 } 49 return 0; 50} 51 52 53bool push(int data) 54{ 55 if(is_full()) 56 return false; 57 else 58 { 59 stack[top++] = data; 60 return true; 61 } 62} 63 64int pop(void) 65{ 66 if(is_empty()){ 67 fprintf(stderr,"Error: stack is empty."); 68 return EXIT_FAILURE; 69 } 70 else { 71 return stack[--top]; 72 } 73} 74 75bool is_full(void) 76{ 77 return top==STACKSIZE; 78} 79 80bool is_empty(void) 81{ 82 return top==0; 83} 84

###試したこと
pop関数を書き換えてみたりwhile文のなかをいじってみたりしました。
###補足情報(言語/FW/ツール等のバージョンなど)
C言語で作成中です
作成したVisualStudioは古いバージョンなのでboolを定義しなければいけませんでした。
push(10)の10は適当に当てはめただけなので特に意味はありません。
txst.txtは自分が使ったファイルなのですが、()しか書いていないファイルです。

どこを直せば正常に動くようになるのか、プログラムの書き方自体間違っているのかなど詳しく教えていただけるととても助かります。どうか回答をよろしくお願いいたします。

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

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

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

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

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

guest

回答2

0

条件分の書き方が間違っています。比較は'('と'{'それぞれで行わないといけません

if((ch == '(') || (ch == '{')){

(まとめて書ける言語のほうが意外と少ないです。)
あとは
・"(}"というような入力でも対として判定される。
pushにchを入れてpopで対か判定すればいいと思います。
・終了判定が間違っている
( か { で1足して ) か } で1引くので全部が対になっているということは最後が0ならOKです。
ですのでプログラムの最後でスタックが空なら、問題ないと判定できます。

投稿2016/09/16 12:23

toki_td

総合スコア2850

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

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

KSKS

2016/09/16 13:21

回答ありがとうございます!条件文の文字での「または」について学ぶことができ、プログラムにも反映させることができました。ありがとうございます。 しかし終了判断のところについてがまだ解決できません。 stack[0]=0をmainの中にいれ、 if (stack[top] == 0) { printf("問題はありません。\n"); } else { printf("カッコについて問題があります。\n"); } としたのですが、一向にうまくいきません。もし可能でしたら、ここの部分についてもう少しおしえていただくことはできないでしょうか? プログラムを貼ってしまいコメントが長くなったことお詫び申し上げます。 どうかよろしくお願いいたします。
toki_td

2016/09/16 15:40

あぁ、僕の書き方が悪かったですね、、、 >最後が0ならOKです。 これは「最後がスタックの中の数が0個(つまり空)ならOKです。」という意味です。 ”(())”と入力されると2つ入れて2つ出して終わりなので最後は空ですよね? 正しく対になっていればいくつであろうと最後は必ず空になるのでその時は正しいと判定できます。
KSKS

2016/09/17 06:41

最後の条件式を空なら問題ないという条件式にすればよいのですね! なんとかプログラムを作ることができたようです。返答ありがとうございました。
guest

0

ベストアンサー

こんにちは。

コンパイル・エラーを修正して走らせましたが、「問題はありません」しか表示されないようです。

まず、懸念されているif(ch ==( '(' || '{') )はその通り間違いです。
||はbool型を両辺に取る演算子です。'(''{'はchar型ですから暗黙の型変換でbool型へ変換されます。0はfalse、0以外はtrueへ変換されます。'(''{'は両方とも0ではありませんので、trueへ変換され、true || trueはtrueです。従って if文は、if (ch == true)と書いているのと同じです。
この比較演算は両辺が暗黙の型変換でint型へ変換されます。trueをint型にした時どんな値になるかは処理系依存ですが、1や-1になることが多いです。恐らくchがそのような値になることはないのでこのif文は常に成立しません。

従って、一度もpush(10)されません。そして、stack[top]は初期化されていませんので不定値です。
それがたまたまた10でない限り最後のif文も成立しないので「問題はありません」となることがほとんどと思います。

if(ch ==( '(' || '{') )の気持ちはわかりますがコンピュータには伝わりませんので、if ((ch == '(') || (ch == '{'))と書きましょう。

次に最後の条件判断もよろしくないです。stackが空でないときや処理中にstackがアンダーフローした時が対応が崩れている時と思います。そのように書きましょう。


ところで、上記を修正したとしてもまだよろしくない筈です。
`({)}'は対応は取れていると判定する筈です。
最後にpushしたものが'('なのか'{'なのかを記録しておき、それと対応していない方がきたら対応ハズレとするべきと思います。この処理はstackを使えば記述できますよ。

投稿2016/09/16 12:19

Chironian

総合スコア23272

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

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

KSKS

2016/09/16 13:16

詳しい回答ありがとうございます! おかげさまで文字の時の条件式について知ることができ、そこを直すことができました。ありがとうございます。 しかし、最後の終了判断についてが未だにわかりません。まず、私がプログラムを実行してみると、逆に「カッコについて間違いがあります」としか表示されません。そして、 stackが空でないときや処理中にstackがアンダーフローした時が対応が崩れているとのご指摘をいただいたので、変えてみようと考えてみたのですが、どうすればいいのか手が動きません・・・・。もし可能でしたら、もう少しヒントをいただきたいと考えております。どうかよろしくお願いします。
Chironian

2016/09/16 14:15

ならば、まずはスタックが空かどうかで判定してみて下さい。スタックが空かどうか判定する関数も作られているので出来ますよね?
KSKS

2016/09/17 06:41

is_empty関数を使って空なら問題ないという条件式にすれば正常に動くのですね! 返答ありがとうございました。 ご指摘いただいた残りのstackを使って行うものも作れたようです。ありがとうございました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問