通过函数传递字符串可以剪切前几个字符

时间:2017-12-16 14:48:15

标签: c stdin

我必须创建一个以中缀表示法表达的代码,并输出正确的答案。

示例输入如下:

3
2.8982 + 4.8674 - 5.5170 - 1.4080 + 3.6204 - 3.8340 - 5.9121
1.8752 ^ 3.7947 ^ 3.9259 / 5.0828 ^ 2.3765 ^ 1.6631
3.8120 / 5.3817 * 5.0096 * 1.0598 / 3.7128 + 5.8597 / 4.3995 ^ 5.1891 - 3.0547 / 2.5795

第一个输入是一个整数,表示将跟随多少个表达式。

为了解决这个问题,我创建了一个函数 result(),它接受一个包含表达式的字符串。此函数仅适用于循环的第一次迭代。

从这个错误中,我怀疑是否有一些关于我如何接受输入的东西,所以我在我的main函数中放置了一个print语句,看看我是否从STDIN得到了正确的输入:

int main(void) {
    int num; //get num of expressions
    scanf("%d", &num);
    getchar(); //get newline
    char exp[MAX];
    //gets the whole string of input
    for(int a = 0; a < num; a++) {
        fgets(exp, MAX, stdin);
        exp[strlen(exp)-1] = 0;
        printf("STDIN: %s\n", exp);
        //double ans = result(exp);
        memset(exp, 0, MAX);
        //printf("%0.4lf\n\n", ans);
    }
}

这是我的输出:

STDIN: 2.8982 + 4.8674 - 5.5170 - 1.4080 + 3.6204 - 3.8340 - 5.9121
STDIN: 1.8752 ^ 3.7947 ^ 3.9259 / 5.0828 ^ 2.3765 ^ 1.6631
STDIN: 3.8120 / 5.3817 * 5.0096 * 1.0598 / 3.7128 + 5.8597 / 4.3995 ^ 5.1891 - 3.0547 / 2.5795

所以,从这里开始,我知道STDIN确实得到了正确的输入。接下来,在我的结果函数中,我放置了一个print语句,用于检查输入到函数中的字符串的值。现在,如果我取消注释main中调用函数结果的行,并输入相同的输入,我会得到不同的输出。

STDIN: 2.8982 + 4.8674 - 5.5170 - 1.4080 + 3.6204 - 3.8340 - 5.9121
FUNCTION: 2.8982 + 4.8674 - 5.5170 - 1.4080 + 3.6204 - 3.8340 - 5.9121

STDIN: 947 ^ 3.9259 / 5.0828 ^ 2.3765 ^ 1.6631
FUNCTION: 947 ^ 3.9259 / 5.0828 ^ 2.3765 ^ 1.6631

STDIN:  5.3817 * 5.0096 * 1.0598 / 3.7128 + 5.8597 / 4.3995 ^ 5.1891 - 3.0547 / 2.5795
FUNCTION:  5.3817 * 5.0096 * 1.0598 / 3.7128 + 5.8597 / 4.3995 ^ 5.1891 - 3.0547 / 2.5795

为什么会这样?即使我删除函数中的print语句,也会发生此错误。只要我调用函数 result()

,就会发生这种情况

当我调用函数时从STDIN输入:

STDIN: 2.8982 + 4.8674 - 5.5170 - 1.4080 + 3.6204 - 3.8340 - 5.9121
STDIN: 947 ^ 3.9259 / 5.0828 ^ 2.3765 ^ 1.6631
STDIN:  5.3817 * 5.0096 * 1.0598 / 3.7128 + 5.8597 / 4.3995 ^ 5.1891 - 3.0547 / 2.5795

我怀疑它与空白有关,但我无法弄清楚该错误会发生在哪里?我已经处理好换行了吗?

完整代码:

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <math.h>
#include <ctype.h>
#define MAX 100000

struct Stack {
    int data[MAX];
    int top;
};
typedef struct Stack Stack;

double numbers[MAX]; //stack for numbers
int numTop;

void Initialize(Stack *S) {
    S->top = -1;
    memset(S->data, 0, MAX);
}

void initNumbers() {
    numTop = -1;
    memset(numbers, 0, MAX);
}

char peek(Stack *S) {
    return S->data[S->top];
}

void push(Stack *S, char c) {
    S->top++;
    S->data[S->top] = c;
}

char pop(Stack *S) {
    char value = S->data[S->top];
    S->top--;
    return value;
}

int isEmpty(Stack *S) {
    if(S->top == -1) {
        return 1; //empty
    } else {
        return 0;
    }
}

int isDigit(char c) {
    if(c >= '0' && c <= '9' || c == '.') {
        return 1;
    } else {
        return 0;
    }
}

int isOperation(char c) {
    if(c == '+' || c == '-' || c == '*' || c == '/' || c == '^') {
        return 1;
    } else {
        return 0;
    }
}

double ConvertTodouble(char exp[], int a, int size) {
    char temp[MAX];
    memset(temp, 0, MAX);
    for(int i = 0; i < size; i++) {
        temp[i] = exp[a];
        a++;
    }
    return atof(temp);
}

void pushNum(double num) { //for num array
    numTop++;
    numbers[numTop] = num;
}

double popNum() {
    double result = numbers[numTop];
    numTop--;
    return result;
}

double evaluate(double a, double b, char op) {
    if(op == '+') {
        return a + b;
    } else if(op == '-') {
        return a - b;
    } else if(op == '*') {
        return a * b;
    } else if(op == '/') {
        return a / b;
    } else if(op == '^') {
        return pow(a, b);
    }
}

int weight(char c) {
    switch(c) {
        case '+':
        case '-': return 1;
                  break;
        case '*': 
        case '/': return 2;
                  break;
        case '^': return 3;
                  break;
    }
}

//if isp > icp, pop (returns 1)
//this returns 1 if isp > icp (left associative)
//returns 1, we pop
int higherPrecedence(char instack, char incoming) { 
    int isp = weight(instack);
    int icp = weight(incoming);

    if((isp == icp) && instack == '^') {
        return 0;
    } else if((isp == icp) && instack != '^') {
        return 1;
    }

    if(isp > icp) {
        return 1;
    } else {
        return 0;
    }
}

double result(char exp[]) {
    Stack S; //stack for operations (+,-,*,/,^)
    double ans = 0;
    Initialize(&S);
    initNumbers();
    int len = strlen(exp);
    int flag = 0;
    for(int i = 0; i < len; i++) {
        if(exp[i] == ' ') {
            getchar();
        } else if(isDigit(exp[i])) {
            //gets number from char array and converts to double
            flag = i; //flag determines how many spaces to move pointer later
            for(int a = i; a < len; a++) {
                if(exp[a] == ' ') {
                    break;
                } else {
                    flag++;
                }
            }
            int size = flag - i;
            double number = ConvertTodouble(exp, i, size);
            pushNum(number);
            i = flag - 1; //update the index so we won't repeat operation
        } else if (exp[i] == '(') {
            push(&S, '(');
        } else if(isOperation(exp[i])) {
            while(!isEmpty(&S) && peek(&S) != '(' && higherPrecedence(peek(&S), exp[i])) {
                char op = pop(&S);
                double b = popNum();
                double a = popNum();
                ans = evaluate(a,b,op);
                pushNum(ans);
            } 
            push(&S, exp[i]);

        } else if(exp[i] == ')') {
            while(!isEmpty(&S) && peek(&S) != '(') {
                char op = pop(&S);
                double b = popNum();
                double a = popNum();
                ans = evaluate(a,b,op);
                pushNum(ans);
            }
            char throw = pop(&S); //this gets the '('
        }
    }
    while(!isEmpty(&S)) {
        char op = pop(&S);
        double b = popNum();
        double a = popNum();
        ans = evaluate(a,b,op);
        pushNum(ans);

        if(numTop == 0) {
            break;
        }
    }
    return ans;
}

int main(void) {
    int num; //get num of expressions
    scanf("%d", &num);
    getchar(); //get newline
    char exp[MAX];
    //gets the whole string of input
    for(int a = 0; a < num; a++) {
        printf("Before: %s\n", exp);
        fgets(exp, MAX, stdin);
        exp[strlen(exp)-1] = 0;
        printf("STDIN: %s\n", exp);
        double ans = result(exp);
        memset(exp, 0, MAX);
        //printf("%0.4lf\n\n", ans);
    }
}

1 个答案:

答案 0 :(得分:1)

嗯,我想我发现了这个错误。

你可以看到这里发生了什么

// fixed header
$(function() {
    $(window).scroll(function() {
        var scroll = $(window).scrollTop();
        if (scroll >= 80) {
            $("body").addClass('fixed');
        } else {
            $("body").removeClass("fixed");
        }
    });
});
12个西卡特失踪了。

检查上一行

1.8752 ^ 3.7947 ^ 3.9259 / 5.0828 ^ 2.3765 ^ 1.6631
            ^
            |
           you got it from here.

有12个空格。

所以这就是导致错误的原因。

2.8982 + 4.8674 - 5.5170 - 1.4080 + 3.6204 - 3.8340 - 5.9121
      x x      x x      x x      x x      x x      x x

更改代码的逻辑。希望这会有所帮助。