0

我有一个标准输入,如“ 33 44 55 + 66 * + = ”,(即逆波兰表示法,RPN),我使用如下代码来解析它。但是 scanf("%d") 读取 '+' 并丢弃它,如何对运算符进行 ungetc 并使其被 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 以逐个进行计算,从而使这种评估器变得非常简单和健壮。

于 2011-12-24T19:06:51.047 回答
0

无法通过 scanf 取消等。再次在同一点使用 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 回答
0

强烈建议:

  1. 使用 fgets() 获取字符串。这样做有很多很多很好的理由。

  2. 一旦你得到了字符串,如果你愿意,试着用 sscanf() 解析它。

    "sscanf()" 与 "scanf" 相同——除了它适用于内存中的字符串(而不是直接读取标准输入)。

  3. 如果您愿意,也可以使用 strtok()。或者编写自己的函数来解析和解释字符串。

  4. 我怀疑你会发现 sscanf() 对于你的目的来说太有限了。但是如果你想尝试一下——如果只是出于好奇——很酷。帮自己一个忙,先使用“fgets()”从标准输入获取输入。

恕我直言.. 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 回答