c - 解析简单的数学表达式
问题描述
我正在尝试使用命令行输入编写一个简单的数学表达式解析器。表达式将仅包含 +-*/ 操作,并且从左到右进行评估。
#include <stdio.h>
#include <stdlib.h>
//does not work for double digit inputs
int main (int argc, char *argv[])
{
if (argc == 1)
{
printf("\n======================================================== \n");
printf("Invalid usage: <ProgramName>.exe <MathExpression:string> \n");
printf("eg: 2+3/5*9 \n");
printf("======================================================== \n");
return 0;
}
char *expr = argv[1];
float answer = (float)expr[0]-'0';
for (int i = 2; i < strlen(expr); i+=2) {
if (expr[i-1] == '+')
answer += (float)expr[i]-'0';
else if (expr[i-1] == '-')
answer -= (float)expr[i]-'0';
else if (expr[i-1] == '*')
answer *= (float)expr[i]-'0';
else if (expr[i-1] == '/')
answer /= (float)expr[i]-'0';
}
printf("answer: %.2f", answer);
}
我编写的程序适用于单个数字输入,例如 3+4+5,但不适用于 10 以上的输入(例如 10+11+12)。知道如何解决这个问题吗?
解决方案
要将字符串中的数字解析为double
,您可以使用strtod()
:
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char *argv[]) {
if (argc == 1) {
printf("\n========================================================\n");
printf("Invalid usage: <ProgramName>.exe <MathExpression:string>\n");
printf("eg: 2+3/5*9\n");
printf("========================================================\n");
return 0;
}
char *expr = argv[1];
double answer = strtod(expr, &expr);
while (*expr) {
if (*expr == ' ' || *expr == '\t')
expr++;
else if (*expr == '+')
answer += strtod(expr + 1, &expr);
else if (*expr == '-')
answer -= strtod(expr + 1, &expr);
else if (*expr == '*')
answer *= strtod(expr + 1, &expr);
else if (*expr == '/')
answer /= strtod(expr + 1, &expr);
else
break;
}
printf("answer: %.2f\n", answer);
return 0;
}
请注意,无效输入可能会产生令人惊讶的结果。这是检测无效输入的简单方法:
#include <stdio.h>
#include <stdlib.h>
double get_number(const char *expr, char **nextp) {
double value = strtod(expr, nextp);
if (expr == *nextp) {
fprintf(stderr, "invalid input: %s\n", expr);
exit(1);
}
return value;
}
int main(int argc, char *argv[]) {
if (argc == 1) {
printf("\n========================================================\n");
printf("usage: <ProgramName>.exe <MathExpression:string>\n");
printf("eg: '2+3/5*9'\n");
printf("========================================================\n");
return 0;
}
char *expr = argv[1];
double answer = get_number(expr, &expr);
while (*expr) {
if (*expr == ' ' || *expr == '\t')
expr++;
else if (*expr == '+')
answer += get_number(expr + 1, &expr);
else if (*expr == '-')
answer -= get_number(expr + 1, &expr);
else if (*expr == '*')
answer *= get_number(expr + 1, &expr);
else if (*expr == '/')
answer /= get_number(expr + 1, &expr);
else {
printf("invalid input: %s\n", expr);
break;
}
}
printf("answer: %.2f\n", answer);
return 0;
}
推荐阅读
- javascript - javascript innerHTML 在 asp.net 网络表单中不起作用
- vba - 将多个 Excel 文件合并为一个新的 Excel 文件
- javascript - 无法使用 firebase 检索特定子项的值
- android - 在单击按钮时更改 baseadapter getview 中的文本颜色
- javascript - 使用带有条件渲染的 refs
- angular - rxjs:EmptyError:序列中没有元素
- ruby-on-rails - Rails Active Admin 基本错误 - 将直接锚链接添加到有错误的字段
- ruby-on-rails - Rails redirect_to 在使用 Turbolinks 时不起作用
- javascript - Javascript / Typescript:Array.prototype.map 函数中的新类实例不持久
- javascript - 使用“inspect”(字符串!)调用代理获取陷阱