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