1

Good day, everyone! I'm new in C++ (and here in stackoverflow as well) and I need help from you experts.

I have here a code that should ask the user for the infix expression then converts it to postfix and outputs the result (postfix calculator). However, I cannot convert postfix to output instantly so as soon as it displays the postfix expression, it asks for the postfix expression again (with spaces after e.g., 1 2 + ) before outputting the real answer.

There is no error or warning but when I run the program, the computer says "file.exe has stopped working" after displaying the postfix expression. So the program is able to convert infix to postfix expression correctly but there is still some jinx when displaying the output.

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

I'm a newbie and I really need help from you experts. I will really appreciate it if you help me correct my program. Thank you very much and have a nice day!

Manishearth
  • 14,882
  • 8
  • 59
  • 76
First Lady
  • 79
  • 2
  • 3
  • 15
  • 2
    Do you know how to use a debugger? If you do, use it to narrow down the problem to a small piece of code. When you do that you might realize you know how to solve it yourself. If you don't then you can post just that code and tell your discoveries so that you can help others help you. Don't expect people to grab your code, compile it, test it, and debug it. If you don't know how to use a debugger, solve that first! A debugger is an essential programmer's tool. – R. Martinho Fernandes Mar 21 '12 at 11:55
  • Oh, and in any case, you seem to be learning mostly C, not C++, so I'll just leave you a link to our [list of good C++ books](http://stackoverflow.com/questions/388242/the-definitive-c-book-guide-and-list). – R. Martinho Fernandes Mar 21 '12 at 11:57

1 Answers1

0

One possible issue is that the pop_for_output() function never checks for an empty/NULL stack like you do in pop(). If an invalid postfix expression is entered, or if your parsing is incorrect, you could very easily get into the case of referencing a NULL pointer which could very well explain the crash.

uesp
  • 6,194
  • 20
  • 15
  • Thank you! I now placed if (!top) { cout << "Stack underflow\n" << endl; return ' '; } inside pop_for_output. The program doesn't display "file.exe has stopped working" but it displays wrong output in the command prompt. – First Lady Mar 21 '12 at 12:31
  • I assume you mean `if (!stack) {...` since you are using a different stack object in the pop/push_for_output() functions. I would just try inputting a simple postfix expression (1 2 +) and step/trace through the code in a debugger, or add logging outputs, to see where the error is. – uesp Mar 21 '12 at 12:48
  • Thanks again but it still displays the wrong output-- be it stack or top. Unfortunately, I don't know how to use (and I don't have) a debugger that's why I find this hard. I'm new in C++. :-) – First Lady Mar 21 '12 at 12:56
  • Instead of a debugger you can add a bunch of `cout << "..."` statements in various places that outputs where it is and the size/contents of the stack. Start with simple input expressions until you find one that doesn't work and then look at the output to see where the parser is not doing what you think it should be. – uesp Mar 21 '12 at 14:09