簡體   English   中英

帶堆棧的C計算器程序

[英]C Calculator Program with Stack

嗨,我完全被這個基本的計算器所困擾。 它幾乎可以完美運行,但是當我嘗試輸入“ 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

isdigit()僅應測試零度

代替:

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

采用:

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

指針可以輕松覆蓋其他地方使用的內存

該代碼可以:

char* hold = malloc(64);

然后在循環上執行:

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

這將導致堆棧上存儲的所有值共享相同的存儲,並在更改holdhold其覆蓋。

分配必須在每次使用時進行:

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM