如何使用 while 循环扫描数字和运算符系列?
我有一个像“ 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));
}
}
I have a stdin input like " 33 44 55 + 66 * + = ", (i.e, Reverse Polish notation,RPN), and I use codes as follows to parse it. But scanf("%d") reads '+' and discards it, how to ungetc the operator and make it be read by scanf(" %c ")? What is the best way to solve the problem. Thanks.
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));
}
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
解决这个问题的最好方法是使用像 ANTLR 这样的解析器生成器。如果您以前没有使用过它,那么需要一些学习,但是有一些关于算术计算的示例和教程,就像您想要做的那样,并且 ANTLR 生成 C 代码,该代码将根据以下内容进行适当、正确的解析工作您定义的语法(与手写的解析代码不同,手写的解析代码即使不是彻底的错误,通常也有怪癖)。
如果您使用 ANTLR,它可以将输入解析为“抽象语法树”或 AST。如果您仔细定义语法,则可以通过简单的递归遍历此 AST 来进行一项一项的计算,从而使这种评估器变得非常简单和强大。
The best way to solve this problem is to use a parser generator like ANTLR. It'll take a bit of learning if you haven't used it before, but there are examples and tutorials for arithmetic calculations like what you want to do, and ANTLR generates C code that will do a proper, correct job of parsing according to the grammar you define (unlike hand-written parsing code, which usually has quirks if not outright bugs).
If you use ANTLR, it can parse the input into an "abstract syntax tree," or AST. If you define your grammar carefully, this AST can be traversed with a straightforward recursion to do the computations, one by one, making this kind of evaluator quite simple and robust.
强烈建议:
使用fgets()获取字符串。这样做有很多很多很好的理由。
一旦你得到了字符串,如果你愿意的话,可以尝试用 sscanf() 来解析它。
“sscanf()”与“scanf”相同 - 不同之处在于它适用于内存中的字符串(而不是直接读取标准输入)。
如果您愿意,也可以使用 strtok()。或者编写您自己的函数来解析和解释字符串。
我怀疑您会发现 sscanf() 对于您的目的来说太有限了。但如果你想尝试一下 - 如果只是出于好奇 - 那就太好了。帮自己一个忙,先使用“fgets()”从标准输入获取输入。
恕我直言..PSM
Strong suggestion:
Get the string with fgets(). There are many, many good reasons for doing so.
Once you've GOT the string, try parsing it with sscanf() if you wish.
"sscanf()" is the SAME as "scanf" - except that it works with in-memory strings (instead of directly reading stdin).
Or use strtok() if you prefer. Or write your own functions to parse and interpret the string.
I suspect you'll find sscanf() is too limited for your purposes. But if you want to try it - if only out of curiousity - cool. Just do yourself a favor and use "fgets()" to get the input from stdin first.
IMHO .. PSM
无法通过 scanf 取消etc。再次在同一点使用 sscanf,或 scanf("%s") ->检查字符串并转换。
例如
Can't ungetc by scanf. use sscanf by same point again, or scanf("%s") -> check string and convert.
E.g.
我建议您使用 Bison(解析器生成器)。
手册中有一个 RPN 计算器的完美示例。本手册各处均使用此示例。
http://www.gnu.org/software /bison/manual/html_node/RPN-Calc.html#RPN-Calc
我建议您从那里阅读它,这比您从这里得到的任何答案都更好。
I recommend you using Bison (a parser generator).
There's a perfect example of a RPN calculator in the manual. This example is used all over the manual.
http://www.gnu.org/software/bison/manual/html_node/RPN-Calc.html#RPN-Calc
I recommend you reading it from there, which will be better than any answer you could get from here.