I am trying to make an expression calculator and it works ok, but only for single digit numbers. I take in the expression in infix notation and then convert it to postfix notation. I just am not sure how to allow it calculate the correct answer with double digits. I though about having a while loop on the isdigit(*p) part and combing all the numbers to a string but if the input was 15+3 postfix would be 153+ and therefore it would make the number 153 instead of 15. Hopefully some one can help me or point me in the right direction. Thanks.

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

int priority(char c) {
	int rank;
	if (c == '*' || c == '/')
		rank = 1;
	else  if (c == '+' || c == '-')
		rank = 2;
	return rank;
}

string infixPostfix(string infix){
	stack<char> st;
	int i = 0;
	string out;

	while(infix.length() != i){
		if (infix[i] == '+' || infix[i] == '-' || infix[i] == '*' || infix[i] == '/'){
			while (!st.empty()){
				if(priority(st.top()) <= priority(infix[i])){
					out.push_back(st.top());
					st.pop();
				}
				else break;
			}
			st.push(infix[i]);
		} 

		else if (infix[i] == '(') 
			st.push(infix[i]);

		else if (infix[i] == ')') {
			while (st.top() != '(') {
				out.push_back(st.top());
				st.pop();
			}
			st.pop();
		} 

		else
			out.push_back(infix[i]);  
		i++;
	}

	while (!st.empty()){
		out.push_back(st.top());
		st.pop();
	}

	return out;
}

int evaluate(char *postfix){
	char *p, t,*q;
	stack <int> st;
	int num1, num2, result;
	p=&postfix[0];



	while(*p != NULL){
		while(*p == ' ')
			p++;
		


		if(isdigit(*p)){
			t= *p;
			q =&t;
			st.push(atoi(q));
		}

		else{
			num1 = st.top();
			st.pop();
			num2 = st.top();
			st.pop();

			switch(*p){
			case '+':
				result = num2  + num1;
				break;
			case '-':
				result = num2 - num1;
				break;
			case '/':
				result = num2 / num1;
				break;
			case '*':
				result = num2 * num1;
				break;
			default: 
				return 0;
			}
			st.push(result);
		}
		p++;
	}
	result = st.top();
	st.pop();
	return result;
}
void main() {
	string infix, postfix;
	cout << "Enter an infix expression: " << endl;
	getline(cin, infix);
	cout << endl;

	postfix = infixPostfix(infix);

	cout << "Infix:   " << infix << endl;
	cout << "Prefix:  " << endl;
	cout << "Postfix: " << postfix << endl;
	cout << endl;

	cout << "Answer:  " << evaluate(&postfix[0]) << endl;
	cout << endl;
}

You would do better with a stack of strings rather than chars, I think. You then could tokenize the input into strings, and push the strings onto the stack.

A better approach might be to use a discriminant union (that is, a structure with a type marker and a union holding different possible values) to represent the tokens:

enum TOKEN_TYPE {INTEGER, RPAREN, LPAREN, OPERAND};

struct Token
{
    TOKEN_TYPE type;
    union
    {
        char operand;
        int integer; 
    } value;
};

stack<Token> st;

Better still might be to make an abstract Token class, then subclass it with IntToken and OpToken classes, which then could have the appropriate variables and methods to hold and return the values appropriately.

Edited 5 Years Ago by Schol-R-LEA: n/a

Is there anyway whatsoever to do it with what I already have so I don't have to rewrite my whole function?

You may be able to modify it such that it inserts a space when an operator is found, but I'm not sure that it would work consistently.

This article has been dead for over six months. Start a new discussion instead.