2011-12-24 17 views
0

我有一個stdin輸入,如「33 44 55 + 66 * + =」(即Reverse Polish notation,RPN),我使用如下代碼來解析它。但是scanf(「%d」)讀取'+'並丟棄它,如何取消操作並使其被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)'。 – 2011-12-24 18:09:24

+5

你必須使用'scanf()'?交互式輸入通常不合適。使用'fgets()'並自己解析輸入字符串。 – 2011-12-24 18:10:16

+0

@Carl:strtok可能不會很好,deltrs將被strtok(3)丟棄。 – 2011-12-24 19:36:39

回答

1

解決此問題的最佳方法是使用解析器生成器,如ANTLR。如果你之前沒有使用它,需要學習一些知識,但是有一些算術計算的例子和教程,比如你想做什麼,ANTLR生成C代碼,這些代碼將根據你定義的語法(不像手寫的解析代碼,如果沒有徹底的錯誤,通常會有怪癖)。

如果您使用ANTLR,它可以將輸入解析爲「抽象語法樹」或AST。如果你仔細地定義你的語法,這個AST可以通過一個簡單的遞歸遍歷來逐個完成計算,使得這種評估器非常簡單和強大。

0

無法通過scanf取消保存。再次使用同一點的sscanf,或scanf(「%s」) - >檢查字符串並進行轉換。

E.g.

#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獲得輸入。

恕我直言.. PSM