我的作业有问题。我有一些由老师编写的代码,我想编辑它以制作计算器。所以我添加了几行,我认为它会起作用,但遗憾的是并非如此。程序总是返回操作数或运算符错误。你能来看看吗?
的main.c
#include "stdio.h"
#include "evalexpression.h"
int main() {
char string[100];
int result;
result = InterCalc(string);
CalcFilter(result, string);
return 0;
}
evalexpression.c
#include "stdio.h"
#include "string.h"
#include "evalexpression.h"
#include "math.h"
#include "float.h"
static float f1, f2;
static char op;
int isValidExpression(const char *str) {
int res;
char ops[10];
res = sscanf(str, "%f %s %f", &f1, ops, &f2);
if (res == 3) {
if (ops[0] == '+' || ops[0] == '-' || ops[0] == '^' || ops[0] == '*' || ops[0] == '/') {
op = ops[0];
return 1;
} else
return 0;
} else
return 0;
}
int getOperator() {
return (op);
}
float getFstOperand() {
return (f1);
}
float getSecOperand() {
return (f2);
}
float getExprValue() {
int operation;
operation = getOperator();
switch (operation) {
case 1:
return (getFstOperand() + getSecOperand());
break;
case 2:
return (getFstOperand() - getSecOperand());
break;
case 3:
return (getFstOperand() / getSecOperand());
break;
case 4:
return (getFstOperand() * getSecOperand());
break;
case 5:
return (pow(getFstOperand(), getSecOperand()));
break;
default:
return 0;
}
}
int InterCalc(char *my_string) {
fgets(my_string, sizeof(my_string), stdin);
if (strcmp(my_string, "exit\n") == 0) {
printf("Program ended\n");
return 0;
} else
if (isValidExpression(my_string) == 0) {
printf("Expression error\n");
return 0;
} else
return 1;
}
void CalcFilter(int a, char *str) {
float calculation_value;
printf("Press 'E' to display the invalid line or press 'V' to display the valid line\n");
int choice;
choice = getchar();
switch (choice) {
case 'E':
case 'e':
if (a == 0) printf("The line %s is invalid.\n", str);
else if (a == 1) printf("There's nothing wrong with the line %s\n", str);
break;
case 'V':
case 'v':
if (a == 1) {
calculation_value = getExprValue();
printf("The result of %s is %f.\n", str, calculation_value);
}
if (a == 0) printf("The line %s is invalid\n", str);
break;
default:
printf("You haven't chosen the valid option of the switch\n");
break;
}
}
答案 0 :(得分:0)
您应该将目标缓冲区的大小传递给函数InterCalc()
。如上所述,它一次只能读取sizeof(char*) - 1
个字节。您还应该检查文件的结尾。
int InterCalc(char *my_string, size_t size) {
if (fgets(my_string, size, stdin) == NULL
|| strcmp(my_string, "exit\n") == 0) {
printf("Program ended\n");
return 0;
} else
if (isValidExpression(my_string) == 0) {
printf("Expression error\n");
return 0;
} else {
return 1;
}
}
从main()
调用:
#include <stdio.h>
#include "evalexpression.h"
int main(void) {
char string[100];
int result;
result = InterCalc(string, sizeof(string));
CalcFilter(result, string);
return 0;
}
注意:
您应该使用标准标题的<stdio.h>
语法。
您应该通过在%s
中传递sscanf()
格式的最大字符数来防止缓冲区溢出:sscanf(str, "%f %9s %f", &f1, ops, &f2);
编辑:GetExrValue()
还有另一个问题:您为0
而不是操作字符打开5
到op
的值。以下是纠正此问题的方法:
float getExprValue(void) {
switch (getOperator()) {
case '+':
return getFstOperand() + getSecOperand();
case '-':
return getFstOperand() - getSecOperand();
case '/':
return getFstOperand() / getSecOperand();
case '*':
return getFstOperand() * getSecOperand();
case '^':
return pow(getFstOperand(), getSecOperand());
default:
return 0;
}
}