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

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

ただいまの
回答率

89.99%

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

解決済

回答 2

投稿

  • 評価
  • クリップ 0
  • VIEW 1,853

KSKS

score 5

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

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

発生している問題・エラーメッセージ

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

該当のソースコード

#include <stdio.h>
#include <stdlib.h>
#define true 1        
#define false (!true)    
#define STACKSIZE 20
//typedef int bool;        
#define bool int

bool push(int data);
int pop(void);
int peek(void);
bool is_full(void);
bool is_empty(void);
void print_stack(void);

int stack[STACKSIZE];
int top=0;

int main(void)
{

    FILE *fp;        
    char fname[] = "text.txt";    
    char ch;

    fp = fopen(fname,"r");    
    if(fp == NULL){
        fprintf(stderr,"Can't open %s.\n",fname);
        return EXIT_FAILURE;
    }else{
        while((ch=fgetc(fp)) != EOF){
            if(ch ==( '(' || '{') ){    
                push(10);
            }
            else if(ch==( ')' || '}' )){
                pop();
            }
        }

    printf("\n");
    fclose(fp);        
    }

    if(stack[top]==10
        printf("カッコについて間違いがあります。\n");
    }else {
        printf("問題はありません。\n");
    }
    return 0;
}


bool push(int data)
{
    if(is_full())    
        return false;
    else
    {
        stack[top++] = data;
        return true;
    }
}

int pop(void)
{
    if(is_empty()){    
        fprintf(stderr,"Error: stack is empty.");
        return EXIT_FAILURE;
    }
    else {
        return stack[--top];
    }
}

bool is_full(void)
{
    return top==STACKSIZE;
}

bool is_empty(void)
{
    return top==0;
}

試したこと

pop関数を書き換えてみたりwhile文のなかをいじってみたりしました。

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

C言語で作成中です
作成したVisualStudioは古いバージョンなのでboolを定義しなければいけませんでした。
push(10)の10は適当に当てはめただけなので特に意味はありません。
txst.txtは自分が使ったファイルなのですが、()しか書いていないファイルです。

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

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

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

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

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 2

checkベストアンサー

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 22:16

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

    キャンセル

  • 2016/09/16 23:15

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

    キャンセル

  • 2016/09/17 15:41

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

    キャンセル

0

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

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

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

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2016/09/16 22:21

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

    キャンセル

  • 2016/09/17 00:40

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

    キャンセル

  • 2016/09/17 15:41

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

    キャンセル

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

  • ただいまの回答率 89.99%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

同じタグがついた質問を見る