2011-12-24 2 views
0

「33 44 55 + 66 * + =」(つまり逆ポーランド記法、RPN)のような標準入力があり、次のようにコードを解析して解析します。しかし、scanf( "%d")は '+'を読んでそれを破棄し、演算子をungetcしてscanf( "%c")で読み取らせる方法は?問題を解決する最良の方法は何ですか?ありがとう。whileループを使用して数値と演算子のシリーズをスキャンする方法は?

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)); 
    } 
} 
+0

あなたは 'strtok(3)'をチェックアウトすることができます。 –

+5

'scanf()'を使用する必要がありますか?通常、対話型入力には適していません。 'fgets()'を使い、入力文字列を自分で解析します。 –

+0

@Carl:strtokは大して問題ありません。デリミタはstrtok(3)によって破棄されます。 –

答えて

1

この問題を解決する最良の方法は、ANTLRのようなパーサジェネレータを使用することです。あなたがそれを以前に使っていないのであれば、ちょっと勉強になりますが、あなたのやりたいような算術計算の例やチュートリアルがあります。ANTLRは適切な正しい構文解析の仕事をするCコードを生成します。あなたが定義した文法(手書きの解析コードとは異なりますが、通常は完全なバグではないにもかかわらず)があります。

ANTLRを使用する場合は、入力を「抽象構文ツリー」またはASTに解析できます。文法を慎重に定義すると、このASTを簡単な再帰で横断することができ、計算を1つずつ実行して、この種の評価者を非常に単純で堅牢なものにします。

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; 
} 
0

強力な提案:

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

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

    "sscanf()"は "scanf"と同じですが、(stdinを直接読み込む代わりに)メモリ内の文字列で動作する点が異なります。

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

  4. あなたはsscanf()があなたの目的にはあまりにも限定されていると思うでしょう。しかし、あなたがそれを試してみたいと思えば - 奇妙なことからだけ - 冷たい。ちょうどあなた自身の好意を持って、 "fgets()"を使ってstdinからの入力を最初に取得してください。

IMHO .. PSM

0

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

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

私はあなたがここから得ることができる任意の答えよりも良くなる、あなたはそこからそれを読んでお勧めします。

関連する問題