如何使用while循环扫描数字和运算符序列?

时间:2011-12-24 18:07:02

标签: c loops scanf rpn postfix-notation

我有一个stdin输入,如“33 44 55 + 66 * + =”,(即反向波兰表示法,RPN),我使用以下代码进行解析。但是scanf(“%d”)读取'+'并丢弃它,如何取消操作符并使其被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 个答案:

答案 0 :(得分:1)

解决此问题的最佳方法是使用像ANTLR这样的解析器生成器。如果您之前没有使用它,需要学习一些知识,但是有一些算法计算的示例和教程就像您想要做的那样,并且ANTLR会生成C代码,这些代码将根据以下内容进行正确,正确的解析工作。您定义的语法(与手写的解析代码不同,如果不是彻头彻尾的错误,通常会有怪癖)。

如果使用ANTLR,它可以将输入解析为“抽象语法树”或AST。如果你仔细定义你的语法,可以通过一个简单的递归遍历这个AST,逐个进行计算,使这种评估器非常简单和健壮。

答案 1 :(得分:0)

不能通过scanf ungetc。再次使用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;
}

答案 2 :(得分:0)

强烈建议:

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

  2. 一旦你输入了字符串,如果你愿意,可以尝试用sscanf()解析它。

    “sscanf()”是SAME的“scanf” - 除了它适用于内存中的字符串(而不是直接读取标准输入)。

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

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

  5. 恕我直言.. PSM

答案 3 :(得分:0)

我建议您使用Bison(解析器生成器) 这是手册中RPN计算器的完美示例。本示例全部用于手册。

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

我建议你从那里阅读,这比你从这里得到的任何答案都要好。