逆ポーランドについて教えて下さい。

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
Toshita
記事: 23
登録日時: 8年前

逆ポーランドについて教えて下さい。

#1

投稿記事 by Toshita » 8年前

逆ポーランドについて教科書のソースを書き換えて、
(9+8)-6*3/9 ↓
input: 98+63*9/-=
output: 15
となるように書き換えたり、消したりしたのですが、結局よくわからず、コンパイルできるけどどうやってもstderrとでてしまいます。
条件1:扱う数字は1つのみ。
条件2:空白による区切りを使わない。
なのですが、どこをどう直せばいいのか、ご教授お願いします。

コード:

#include<stdio.h>
#include<stdlib.h>
#include<ctype.h>

typedef long ELEM;                      /*スタックの要素の型*/
#define STACK_SIZE 100                  /*スタックの大きさ*/
ELEM stack[STACK_SIZE];                 /*スタックの定義*/
int n;                                  /*スタックポインタ*/

/*エラーメッセージをプリントしてexit*/

void error(){
        printf("stderr");
        exit(1);
}

/*スタックの初期化*/
void init(){
        n = 0;
}

/*スタックにデータを積む*/
void push(ELEM x){
        if(n >= STACK_SIZE) error();
        stack[n++] = x;
}

/*スタックからデータを降ろす*/
ELEM pop(){
        if(n <= 0) error();
        return stack[--n];
}

/*スタックが空かどうかを調べる*/
/*空なら1,空でなければ0を返す*/
int empty(){
        return n==0;
}

/*********************************************************************/
/*逆ポーランド電卓プログラム*/

main(){
        int c;
        long x,a,b;

        init();
        while ((c=getchar()) != EOF){
                if(isdigit(c)){
                        ungetc(c,stdin);
                        scanf(" %ld",&x);
                        push(x);
                }
                else{
                        switch(c){
                                case '+':
                                        b = pop();
                                        a = pop();
                                        push(a + b);
                                        break;
                                case '-':
                                        b = pop();
                                        a = pop();
                                        push(a - b);
                                        break;
                                case '*':
                                        b = pop();
                                        a = pop();
                                        push(a * b);
                                        break;
                                case '/':
                                        b = pop();
                                        a = pop();
                                        push(a / b);
                                        break;
                                case '=':
                                        if(! empty())
                                        printf("答えは%ldです\n",pop());
                                        init();
                                        break;
                                case ' ':
                                case '\n':
                                case '\t':
                                /*何もせず読みとばす*/
                                        break;
                                        default:
                                        printf("不正な文字がありました。\n");
                                        printf("入力資なおして下さい。\n");
                                        while((c = getchar()) != EOF && c != '\n');
                                                break;
                        }
                }
        }
}
最後に編集したユーザー Toshita on 2015年11月11日(水) 21:11 [ 編集 1 回目 ]

Toshita
記事: 23
登録日時: 8年前

Re: 逆ポーランドについて教えて下さい。

#2

投稿記事 by Toshita » 8年前

あ、扱う数字は1桁です。

かずま

Re: 逆ポーランドについて教えて下さい。

#3

投稿記事 by かずま » 8年前

Toshita さんが書きました:あ、扱う数字は1桁です。
scanf(" %ld",%x); を scanf("%1ld", &x); に変えて見てください。
パーセント、イチ、エル、ディー

アバター
みけCAT
記事: 6734
登録日時: 13年前
住所: 千葉県
連絡を取る:

Re: 逆ポーランドについて教えて下さい。

#4

投稿記事 by みけCAT » 8年前

ソースコードを提示する際は、BBCodeを有効にした(無効にしない)状態でcodeタグで囲んでいただけると、見やすくてありがたいです。
Toshita さんが書きました: ungetc(c,stdin);
scanf(" %ld",&x);
push(x);
少なくとも、この部分がダメです。
scanfで複数の数字が読み込まれ、意図しない動作になってしまいます。
C言語の数字の文字コードは連続しているので、ungetcやscanfを使わず、素直に

コード:

push(c-'0');
でいいでしょう。
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)

box
記事: 2002
登録日時: 13年前

Re: 逆ポーランドについて教えて下さい。

#5

投稿記事 by box » 8年前

Toshita さんが書きました: となるように書き換えたり、消したりしたのですが、結局よくわからず、コンパイルできるけどどうやってもstderrとでてしまいます。
本当にコンパイルできていますか?
Toshita さんが書きました:

コード:

            case ' ':
ここに、よけいな全角空白があるように見えて仕方がありません。
したがいまして、
もし、「コンパイルできるけど」という言説が正しいならば、提示されているコードがお手元にあるコンパイルできるコードと食い違っています。
もし、提示されているコードがお手元にあるもの自身ならば、「コンパイルできるけど」という言説が正しくありません。

さあ、どっちでしょうか。
バグのないプログラムはない。
プログラムは思ったとおりには動かない。書いたとおりに動く。

アバター
みけCAT
記事: 6734
登録日時: 13年前
住所: 千葉県
連絡を取る:

Re: 逆ポーランドについて教えて下さい。

#6

投稿記事 by みけCAT » 8年前

オフトピック
Visual C++だとコードの文字列やコメント以外に全角スペースがあっても問題なくコンパイルが通ってしまう…わけではないのか。
zenkakutest_20151110.png
テスト
zenkakutest_20151110.png (49.56 KiB) 閲覧数: 3303 回
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)

box
記事: 2002
登録日時: 13年前

Re: 逆ポーランドについて教えて下さい。

#7

投稿記事 by box » 8年前

その処理系は使っていませんので何ともいえないところではありますが、
くだんのcase文をコンパイルエラーにしない処理系はあまり使いたくない、というのが本音です。
バグのないプログラムはない。
プログラムは思ったとおりには動かない。書いたとおりに動く。

Toshita
記事: 23
登録日時: 8年前

Re: 逆ポーランドについて教えて下さい。

#8

投稿記事 by Toshita » 8年前

皆さん有難うございました。
scanfで1つだけ読み込ませることで解決しました。
掲示板のことも教えていただき、大変助かりました。

アバター
みけCAT
記事: 6734
登録日時: 13年前
住所: 千葉県
連絡を取る:

Re: 逆ポーランドについて教えて下さい。

#9

投稿記事 by みけCAT » 8年前

解決したのでしたら、「解決チェック」をお願いします。
解決チェックをするには、投稿画面の「送信」の右側にある「解決!」にチェックを入れた状態で返信を投稿してください。
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)

閉鎖

“C言語何でも質問掲示板” へ戻る