我有一个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));
}
}
答案 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)
强烈建议:
使用fgets()获取字符串。这样做有很多很好的理由。
一旦你输入了字符串,如果你愿意,可以尝试用sscanf()解析它。
“sscanf()”是SAME的“scanf” - 除了它适用于内存中的字符串(而不是直接读取标准输入)。
如果您愿意,可以使用strtok()。或编写自己的函数来解析和解释字符串。
我怀疑你会发现sscanf()对你的目的来说太有限了。但如果你想尝试一下 - 如果只是出于好奇 - 很酷。只是帮自己一个忙,并使用“fgets()”从stdin获取输入。
恕我直言.. PSM
答案 3 :(得分:0)
我建议您使用Bison(解析器生成器) 这是手册中RPN计算器的完美示例。本示例全部用于手册。
http://www.gnu.org/software/bison/manual/html_node/RPN-Calc.html#RPN-Calc
我建议你从那里阅读,这比你从这里得到的任何答案都要好。