程序未收到所需的输入

时间:2016-11-13 14:55:25

标签: c arrays if-statement switch-statement

我的作业有问题。我有一些由老师编写的代码,我想编辑它以制作计算器。所以我添加了几行,我认为它会起作用,但遗憾的是并非如此。程序总是返回操作数或运算符错误。你能来看看吗?

的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;
    }
}

1 个答案:

答案 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而不是操作字符打开5op的值。以下是纠正此问题的方法:

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;
    }
}