4

I'm currently learning about data structures, and I'm trying to code a program in C++ that uses an array as a simulated stack. The code is supposed to work like this:

The user inputs a Postfix expression. The expression is read from left to right. Anytime a number is read, it gets "popped" onto the simulated stack. When an operand is read, the top two numbers in the simulated stack are "popped", the operand performs a calculation with those numbers, and the resulting answer gets "pushed" back onto the simulated stack. The process continues until there is only one number left in the simulated stack. This number is the answer to the Postfix expression, and it is read out onscreen to the user.

I have the code (below) working, for the most part. However, if one of the values in my simulated stack is ever greater than or equal to 128, that number seems to be stored incorrectly (for example, +128 becomes -128).

What am I doing wrong? Does it have anything to do with how I'm returning the answer in the calc function? Specifically, this line of code: return answer;

Any help or hints would be much appreciated.

    #include <string>
    #include <iostream>
    using namespace std;

    // Define the size of the stack:
    #define SIZE 50

    // Global variable declarations:
    char stack[SIZE];
    int top = -1; // The top of the array

    // Function for PUSHING operands onto the stack:
    void push(char elem)
    {
        top++;
        stack[top] = elem;
    //    cout << elem << " TESTING PUSH OUTPUT\n"; // TESTING
    }

    // Function for POPPING operands from the stack:
    char pop()
    {
        char answer;
        answer = stack[top];
        top--;
    //    cout << top << " TESTING WHAT'S POPPED\n"; // TESTING
        return (answer);
    }

    // Function for CALCULATING two popped numbers:
    double calc(char op)
    {
        int num1, num2, answer;

        // Pop two numbers from the stack:
        num1 = pop(); 

        num2 = pop(); // put the second popped number into 'num2'

        // Calculate the two popped numbers:
        switch (op)
        {
        case '*':
            answer = num2 * num1;
            break;
        case '/':
            answer = num2 / num1;
            break;
        case '+':
            answer = num2 + num1;
            break;
        case '-':
            answer = num2 - num1;
            break;
        default:
            cout << "Invalid expression!";
        }

        // Push the result of the calculation back onto the stack:
        push(answer);

        return answer;

    }

    // The main program, which takes in the expression:
    int main ()
    {
        string postfix;

        int solution;

        cout << "Please enter a Postfix expression, with operators and operands separated by spaces and/or commas (e.g: 3 7 5 + 2 - * 16 4 + 10 / /): \n";
        getline(cin,postfix);

        // If the User's Postfix expression begins with an operator, then throw up an error message:
        if (postfix.find('/') == 0 || postfix.find('*') == 0 || postfix.find('+') == 0 || postfix.find('-') == 0)
        {
            cout << "Sorry, that's an invalid Postfix expression, and it can't be evaluated.";

            return 0;

        }

        // FOR loop to read the Postfix expression:
        for(unsigned int i = 0; i < postfix.length(); i++)
        {

            // If the value is a space or a comma, move on to the next value:
            if(postfix[i] == ' ' || postfix[i] == ',') 
            {
                continue;
            } // End IF

            // If the value is a number, extract it, and continue reading and extracting the next value until it is NOT a number:
            else if(isalnum(postfix[i]))
            {

                int operand = 0;

                while(i < postfix.length() && isalnum(postfix[i]))
                {
                    // For multi-digit numbers, multiply the initial extracted number by 10 to move it into the 'tens' column, then add the next number to the initial number.
                    // Continue doing this until the next value is NOT a number
                    operand = (operand * 10) + (postfix[i] - '0');
                    i++;
                } // End WHILE

                // When WHILE exits, 'i' will be non-numeric, of the 'end of the string'. Decrement 'i', because it will be incremented in the FOR loop as longs as the FOR condition is true
                // (Stops 'i' from being incremented twice)
                i--;

                // Push the operand onto the stack:
                push(operand);
            } // End ELSE IF

            // If the value is an operator, run the calculation function:
            else
            {
                calc(postfix[i]);
            } // End ELSE

        } // End FOR

        solution = pop(); // put the solution of the equation into 'answer'

        cout << "The solution to the Postfix expression is: " << solution;

    }
Dizzzeh
  • 61
  • 1
  • 10
  • 3
    Your stack elements are `char`, and as it appears your default `char` type must be `signed`. Hence the inability to store anything else than -128..127. – Jongware Nov 07 '15 at 18:08

3 Answers3

2

operand is of type int while push expects a char.

Because on most machines sizeof(int) > sizeof(char), the value of operand might get truncated if it is attempted to be stored in a smaller data type like char.

For example, let's assume sizeof(int) == 4 and sizeof(char) == 1 and a byte is eight bits. Now, if only the 8th bit (starting from 0) is set, a char won't be capable of holding that information and the value 0x100 is truncated to 0x00.

In order to solve this, either make the stack deal with ints or define operand as a char.

Community
  • 1
  • 1
cadaniluk
  • 15,027
  • 2
  • 39
  • 67
  • @tobi303 Oh, yes. Thank ya. – cadaniluk Nov 07 '15 at 18:13
  • ... I can't believe I didn't catch this. Thanks a million @cad, this makes total sense. After making my stack deal with `int`, passing an `int` to the `push` function, and changing the `pop` function to use an `int` as well, everything works as expected. – Dizzzeh Nov 07 '15 at 18:36
1

All you need to do is make your simulated stack of type int instead of char (and other related changes).

Mark B
  • 95,107
  • 10
  • 109
  • 188
1

Your stack is type char which is normally restricted to -128 to 127. Try unsigned char which will probably be 0 to 255. If you need larger values on your stack then you will be to make it an array of ints or something bigger.

bruceceng
  • 1,844
  • 18
  • 23