0

" 33 44 55 + 66 * + = " (つまり、逆ポーランド記法、RPN) のような stdin 入力があり、次のコードを使用して解析します。しかし、scanf("%d") は '+' を読み取り、それを破棄します。オペレーターを unget して、scanf(" %c ") によって読み取られるようにする方法は? 問題を解決する最善の方法は何ですか。ありがとう。

while ((reta = scanf("%d", &operand)) == 1 || (retb = scanf(" %c ", &operator)) == 1) {
  if (reta == 1) push(exprStack, operand);
  else if (retb == 1) {
    operand = pop(exprStack);
    /* function pmtd executes some basic calculation, i.e., plus, minus, times and divide */
    push(exprStack, pmtd(operator, pop(exprStack), operand));
  }
} 
4

4 に答える 4

1

この問題を解決する最善の方法は、ANTLRのようなパーサー ジェネレーターを使用することです。以前に使用したことがない場合は、少し学習する必要がありますが、やりたいことのような算術計算の例とチュートリアルがあり、ANTLR は、適切で正しい解析ジョブを実行する C コードを生成します。定義する文法 (完全なバグではないにしても通常癖がある手書きの構文解析コードとは異なります)。

ANTLR を使用すると、入力を「抽象構文ツリー」または AST に解析できます。文法を慎重に定義すると、この AST を単純な再帰で走査して 1 つずつ計算を実行できるため、この種のエバリュエーターは非常に単純で堅牢になります。

于 2011-12-24T19:06:51.047 に答える
0

強い提案:

  1. fgets() で文字列を取得します。そうするのには多くの正当な理由があります。

  2. 文字列を取得したら、必要に応じて sscanf() で解析してみてください。

    「sscanf()」は「scanf」と同じですが、(stdin を直接読み取るのではなく) インメモリ文字列で動作する点が異なります。

  3. または、必要に応じて strtok() を使用してください。または、独自の関数を作成して、文字列を解析および解釈します。

  4. あなたの目的には sscanf() があまりにも制限されていることがわかると思います。しかし、もしあなたがそれを試してみたいなら - 好奇心から - クールです. 「fgets()」を使用して、最初に stdin から入力を取得してください。

私見..PSM

于 2011-12-24T22:46:29.783 に答える
0

Bison (パーサー ジェネレーター) を使用することをお勧めします。
マニュアルに RPN 電卓の完璧な例があります。この例は、マニュアル全体で使用されています。

http://www.gnu.org/software/bison/manual/html_node/RPN-Calc.html#RPN-Calc

そこから読むことをお勧めします。これは、ここから得られるどの回答よりも優れています。

于 2011-12-24T23:20:16.893 に答える
0

scanf で ungetc を実行できません。同じポイントで sscanf を再度使用するか、scanf("%s") -> 文字列をチェックして変換します。

例えば

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

int main(){
    int reta=0,retb=0;
    int operand;
    char operator;
    char token[16];

    token[15] = '\0';
    while (0 != scanf(" %15s", token)) {
        if(1 == (reta = sscanf(token, "%d", &operand)))
            printf("operand : %d\n", operand);
        else if(1 == (retb = sscanf(token, "%c", &operator))){
            printf("operator : %c\n", operator);
            if(operator == '=') break;
        } else
            printf("else\n");
        reta=retb=0;
    }
    return 0;
}
于 2011-12-24T22:33:13.473 に答える