带堆栈的C计算器程序

时间:2019-02-21 03:30:08

标签: c algorithm stack calculator

嗨,我完全迷上了这个基本的计算器。它几乎可以完美运行,但是当我尝试输入“ 5/5 + 9 * 2”时,堆栈中出了点问题。当应该将5/5中的1加到最后一个循环的18中时,它似乎消失了。发生像2 * 2-9/2这样的模拟输入。只需要帮助找到这个奇怪的错误,我就花了很多小时试图找出运气!谢谢!

#include <stdio.h>
#include<string.h>
#include<stdlib.h>
#include <limits.h>
#include <curses.h>
#include<ctype.h>

struct StackNode
{
    char* data;
    struct StackNode* next;
};

struct StackNode* newNode(char* data)
{
    struct StackNode* stackNode =
    (struct StackNode*) malloc(sizeof(struct StackNode));
    stackNode->data = data;
    stackNode->next = NULL;
    return stackNode;
}

int isEmpty(struct StackNode *root)
{
    return !root;
}

void push(struct StackNode** root, char* data)
{
    struct StackNode* stackNode = newNode(data);
    stackNode->next = *root;
    *root = stackNode;
    printf("%s pushed to stack\n", data);
}

char* pop(struct StackNode** root)
{
    if (isEmpty(*root))
        return NULL;
    struct StackNode* temp = *root;
    *root = (*root)->next;
    char* popped = temp->data;
    free(temp);
    printf("Popped: %s\n", popped);
    return popped;
}

char* peek(struct StackNode* root)
{
    if (isEmpty(root))
        return NULL;
    return root->data;
}

char buffer[64];
char *ca = &buffer[0];
size_t size = 64;
int bufferIndex;
int first = 0;

int isWhiteSpace (char c) {
    if ((c == ' ') || (c == '\t') || (c == '\r')) {
        return 1;
    }
    else {
        return 0;
    }
}

char* getToken() {
    char* token = malloc(64);
    int i = 0;
    while ((isWhiteSpace(buffer[bufferIndex])) && bufferIndex <            strlen(buffer)-1) {
        bufferIndex++;
    }
    while (bufferIndex < strlen(buffer)-1) {
        int num = isWhiteSpace(buffer[bufferIndex]);
        if (num == 0) {
            token[i] = buffer[bufferIndex];
            i++;
            bufferIndex++;
            //printf("%s\n", token);
        }
        else {
            bufferIndex++;
            break;
        }
    }
    token[i] = '\0';
    first++;
    return token;
}

int main()  {
    while (1) {
        char* token = "test";
        char* postFix = "test";
       char* hold = malloc(64);
        postFix = malloc(64);
        int total = 0;
        int pres1 = 0;
        int pres2 = 0;
        struct StackNode* root = NULL;
    printf("Enter line: ");
    getline(&ca,&size,stdin);
    bufferIndex = 0;

    if ((strcmp(token, "quit") == 0)) {
        token = getToken();
        if (strcmp(token, "") == 0) {
            break;
        }
        else {
            printf("Too many arguments. Try again.\n");
            }
        }

else {
    while (strcmp(token, "") != 0) {
        token = getToken();
        //printf("%s\n", token);
        //printf("Top of stack: %s\n", peek(root));
         if (isdigit(*token) == 1) {
            strcat(postFix, token);
            strcat(postFix, " ");
            printf("%s\n", postFix);
        }
        else if (peek(root) == NULL) {
            push(&root, token);
        }
        else {
            printf("Peek: %s\n", peek(root));
            if (strcmp(token, "*") == 0) {
                pres1 = 2;
            }
            else if (strcmp(token, "/") == 0) {
                pres1 = 2;
            }
            else if (strcmp(token, "-") == 0) {
                pres1 = 1;
            }
            else if (strcmp(token, "+") == 0) {
                pres1 = 1;
            }
            else {
                pres1 = 0;
            }
            if (strcmp(peek(root), "*") == 0) {
                pres2 = 2;
            }
            else if (strcmp(peek(root), "/") == 0) {
                pres2 = 2;
            }
            else if (strcmp(peek(root), "-") == 0) {
                pres2 = 1;
            }
            else if (strcmp(peek(root), "+") == 0) {
                pres2 = 1;
            }

            while((peek(root) != NULL) && (pres2 > pres1)) {
                strcat(postFix, peek(root));
                strcat(postFix, " ");
                pop(&root);
                printf("Postfix: %s\n", postFix);
            }
            push(&root, token);
        }
    }
    do {
        //printf("Peek in DO/WHILE: %s\n", peek(root));
        strcat(postFix, peek(root));
        strcat(postFix, " ");
        pop(&root);
    } while ((peek(root) != NULL));
    printf("Postfix: %s\n", postFix);
    //ca = NULL;
    token = "1";
    bufferIndex = 0;
    for (int i = 0; i < strlen(postFix) + 1; i++) {
    buffer[i] = postFix[i];
    }
    //size = strlen(postFix)+1;
    //printf("TOKEN: %s\n", token);

    while (strcmp(token, "") != 0) {
        token = getToken();
        if (isdigit(*token) == 1) {
            //printf("--Token: %s\n", token);
            push(&root, token);
        }

        else {
            int operand1;
            //operand1 = malloc(64);
            int operand2;
            //total = malloc(64);
            printf("Peek: %s\n", peek(root));
            operand2 = atoi(peek(root));
            pop(&root);
            printf("Operand2: %d\n", operand2);
            if (strcmp(token, "") != 0) {
            printf("Peek: %s\n", peek(root));
            operand1 = atoi(peek(root));
            pop(&root);
            printf("Operand1: %d\n", operand1);
            printf("Token: %s\n", token);

            if (strcmp(token, "+") == 0) {
                total = operand1 + operand2;
            }
            else if (strcmp(token, "/") == 0) {
                total = operand1 / operand2;
            }
            else if (strcmp(token, "-") == 0) {
                total = operand1 - operand2;
            }
            else if (strcmp(token, "*") == 0) {
                total = operand1 * operand2;
            }
            sprintf(hold,"%d",total);
            //printf("Peek: %s\n", peek(root));
            push(&root, hold);
            //pop(&root);
            printf("Total: %d\n", total);
        }
            else {
                //printf("Peek: %s\n", peek(root));
                break;
            }
        }
    }
}
    printf("Total: %d\n", total);
}
    return 0;
}

我应该/将其作为作业的参考:http://condor.depaul.edu/ichu/csc415/notes/notes9/Infix.htm

1 个答案:

答案 0 :(得分:1)

isdigit()仅应进行零度测试

代替:

if (isdigit(*token) == 1) {

使用:

if (isdigit((unsigned char)*token)) {

指针使覆盖其他地方使用的内存变得容易

代码执行以下操作:

char* hold = malloc(64);

,然后在循环中执行:

while (/* ... */) {
    // ...
    sprintf(hold,"%d",total);
    push(&root, hold);
    // ...
}

这将导致堆栈上存储的所有值共享相同的存储,并在更改hold时将其覆盖。

分配必须在每次使用时进行:

char *hold;
// ...
while (/* ... */) {
    // ...
    hold = malloc(64);
    sprintf(hold,"%d",total);
    push(&root, hold);
    // ...
}