2012-03-21 83 views
1

美好的一天,大家!我是C++新手(在這裏也是在stackoverflow),我需要你的專家幫助。

使用堆棧將Postfix輸出到輸出(後綴計算器)

我在這裏有一個代碼,應該詢問用戶中綴表達式,然後將其轉換爲後綴並輸出結果(後綴計算器)。但是,我不能立即將postfix轉換爲輸出,所以只要它顯示後綴表達式,它就會在輸出真實答案之前再次請求後綴表達式(在例如1 2 +之後有空格)。

沒有錯誤或警告,但是當我運行該程序時,計算機在顯示後綴表達式後顯示「file.exe已停止工作」。所以程序能夠正確地將中綴轉換爲後綴表達式,但是在顯示輸出時仍然存在一些不祥之兆。

#include <iostream> 
#include <cstring> 
#include <cstdlib> 

using namespace std; 

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

node *top=NULL; 
node *bottom=NULL; 
node *key; 
node *last; 
node *before_last; 


void push (const char Symbol) { 
    key = new node; 
    key->data = Symbol; 
    key->next = top; 
    top = key; 
} 

void push_for_output (node* &stack, int key) { 
    node* newNode = new node; 
    newNode->data = key; 
    newNode->next = stack; 
    stack = newNode; 
} 

const char pop() { 
    if (!top) { 
     cout << "Stack underflow\n" << endl; 
     return ' '; 
    } 
    node* key = top; 
    top = top->next; 
    char ch = key->data; 
    delete key; 
    return ch; 
} 

int pop_for_output (node* &stack) { 
    int key = stack->data; 
    node* nodeToDelete = stack; 
    stack = stack->next; 
    delete nodeToDelete; 
    return key; 
} 

bool isOperator (char *token) { 
    if (strcmp(token, "+") == 0) { 
     return true; 
    } 
    else if (strcmp(token, "-") == 0) { 
     return true; 
    } 
    else if (strcmp(token, "*") == 0) { 
     return true; 
    } 
    else if (strcmp(token, "/") == 0) { 
     return true; 
    } 
    else { 
     return false; 
    } 
} 



const bool is_empty() { 
    return !top; 
} 

int postfix(const char *infix) { 
    char infix_ch[100]={NULL}; 
    char postfix_ch[100]={NULL}; 
    node* stack = NULL; 

    strcpy(infix_ch,"("); 
    strcat(infix_ch, infix); 
    strcat(infix_ch,")"); 

    char symbol[5]={NULL}; 
    char temp[5]={NULL}; 

    for(int i=0; i<strlen(infix_ch); i++) { 
     symbol[0]=infix_ch[i]; 

     if(symbol[0]=='(') 
      push(symbol[0]); 

     else if(symbol[0]==')') { 
      symbol[0]=pop(); 
      while(symbol[0]!='(') { 
       strcat(postfix_ch, symbol); 
       symbol[0]=pop(); 
      } 
     } 

     else if(symbol[0]=='^' || symbol[0]=='*' || symbol[0]=='/' || symbol[0]=='+' || symbol[0]=='-') { 
      if(symbol[0]=='*' || symbol[0]=='/') { 
       temp[0]=pop(); 
       while(temp[0]=='^' || temp[0]=='*' || temp[0]=='/') { 
        strcat(postfix_ch, temp); 
        temp[0]=pop(); 
       } 
       push(temp[0]); 
      } 

      else if(symbol[0]=='+' || symbol[0]=='-') { 
       temp[0]=pop(); 
       while(temp[0]!='(') { 
        strcat(postfix_ch, temp); 
        temp[0]=pop(); 
       } 
       push(temp[0]); 
      } 
      push(symbol[0]); 
     } 

      else 
       strcat(postfix_ch, symbol); 
    } 

     cout << "Postfix: " << postfix_ch; 

     char postfix[80]; 
     cout << "\nEnter postfix expression (include spaces between each operand and/or operator): "; 
     cin.getline(postfix, 80); 
     char *tokens = strtok(postfix, " "); 
     while (tokens != NULL) { 
     if (isOperator (tokens)) { 
      int operand2 = pop_for_output(stack); 
      int operand1 = pop_for_output(stack); 
      int result; 

      if (strcmp(tokens, "+") == 0) { 
       result = operand1 + operand2; 
      } 
      else if (strcmp(tokens, "-") == 0) { 
       result = operand1 - operand2; 
      } 
      else if (strcmp(tokens, "*") == 0) { 
       result = operand1 * operand2; 
      } 
      else if (strcmp(tokens, "/") == 0) { 
       result = operand1/operand2; 
      } 

      push_for_output (stack, result); 
     } 
     else { 
      push_for_output (stack, atoi (tokens)); 
     } 
     tokens = strtok(NULL, " "); 
    } 
    cout << pop_for_output(stack); 
    system("pause"); 
    return 0; 
} 


int main() { 
    char infix_values[100]={NULL}; 
    cout << "Enter the infix equation: "; 
    cin >> infix_values; 
    postfix(infix_values); 
} 

我是一個新手,我真的需要你幫助的專家。如果你幫我糾正我的程序,我將非常感激。非常感謝你,祝你有美好的一天!

+2

你知道如何使用調試器嗎?如果你這樣做,用它來縮小問題的一小段代碼。當你這樣做時,你可能會意識到你知道如何自己解決它。如果你不這樣做,那麼你可以只發布該代碼並告訴你的發現,以便你可以幫助別人幫助你。不要期望人們抓住你的代碼,編譯它,測試它,並調試它。如果您不知道如何使用調試器,請先解決!調試器是必不可少的程序員工具。 – 2012-03-21 11:55:28

+0

哦,無論如何,你似乎主要學習C,而不是C++,所以我只給你一個鏈接到我們的[良好C++書籍清單](http://stackoverflow.com/questions/388242/在-明確-C-書指南和列表)。 – 2012-03-21 11:57:35

回答

0

一個可能的問題是,pop_for_output()函數從不會像在pop()中那樣檢查空/空棧。如果輸入了一個無效的後綴表達式,或者如果解析不正確,那麼可以很容易地引用一個可以很好地解釋崩潰的NULL指針。

+0

謝謝!我現在放置了 如果(!top){cout <<「Stack underflow \ n」<< endl; return''; } 裏面的pop_for_output。該程序不顯示「file.exe已停止工作」,但它在命令提示符下顯示錯誤的輸出。 – 2012-03-21 12:31:48

+0

我假設你的意思是'if(!stack){...',因爲你在pop/push_for_output()函數中使用了不同的堆棧對象。我只是嘗試輸入一個簡單的後綴表達式(1 2 +),並通過調試器中的代碼步進/跟蹤,或者添加日誌記錄輸出,以查看錯誤的位置。 – uesp 2012-03-21 12:48:40

+0

再次感謝,但它仍然顯示錯誤的輸出 - 無論是堆疊還是頂部。不幸的是,我不知道如何使用(我沒有)調試器,這就是爲什麼我覺得這很難。我是C++新手。 :-) – 2012-03-21 12:56:25