Reputation: 69
I'm trying to write a simple mathematical expression parser with inputs from the command line. Expressions will only consist of +-*/ operations, and are evaluated from left to right.
#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);
}
The program that I wrote works well for single digit inputs such as 3+4+5 but will not work for inputs above 10 (such as 10+11+12). Any idea how can I approach this problem?
Upvotes: 1
Views: 89
Reputation: 144705
To parse a number from the string as a double
, you can use 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;
}
Note that invalid input may produce surprising results. Here is a simple way to detect invalid input:
#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;
}
Upvotes: 3