postfix evaluation C++

Started by
7 comments, last by sirGustav 16 years, 12 months ago
Hello, I am trying to evaluate a postfix expression using the following code - for some reason the program halts just inside the for loop. Anyone with any advice regarding this please help. <source> double evaluate_expression(string& postfix, bool& okay) // Process each line for infix-to-postfix conversion and evaluation { const char DECIMAL = '.'; const char LEFT_PARENTHESIS = '('; const char RIGHT_PARENTHESIS = ')'; stack<double> numbers; stack<char> operations; double number = 0; char symbol = ' '; cout << "inside" << endl; for(int i = 0; i < postfix.size(); ++i) { cout << "inside for" << endl; if(postfix == LEFT_PARENTHESIS) { cout << "inside 1st if" << endl; cin >> symbol; operations.push(symbol); } else if(isdigit(postfix) || (postfix == DECIMAL)) { cin >> number; numbers.push(number); cout<< "First Number " << numbers.top() << endl; } else if(strchr("+-*/", postfix) != NULL) { cin >> symbol; operations.push(symbol); cout<< "First Symbol " << symbol << endl; } else if(postfix == RIGHT_PARENTHESIS) { cin.ignore(); do_operation(symbol, numbers, okay); } else cin.ignore(); } return numbers.top(); } </source> thanks for any help offered
Advertisement
You can't use cin here - cin takes input from the standard input (probably what you type). String streams might be a better alternative. These can take input from a string instead of from the user.

However, if you do that, you'll still have another problem: how your for loop is structured means that you will examine every character in the string, even the ones inside the middle of numbers, which you probably didn't want it to.

PS. The source tags need square brackets [smile]
Thanks MR EVIL, i think i have altered the code correctly - but am still in the same predicament, the following has changes I 'think' but still does not get past the first if statement.
double evaluate_expression(istream& in, bool& okay)// Process each line for infix-to-postfix conversion and evaluation {	const char DECIMAL = '.';	const char LEFT_PARENTHESIS = '(';	const char RIGHT_PARENTHESIS = ')';		stack<double> numbers;	stack<char> operations;	double number;	char symbol;		while(in)	{				if(in.peek() == LEFT_PARENTHESIS)		{			in >> symbol;			operations.push(symbol);		}				if(isdigit(in.peek()) || (in.peek() == DECIMAL))		{			in >> number;				numbers.push(number);			cout<< "First Number " << numbers.top() << endl;		}		else if(strchr("+-*/", in.peek()) != NULL)		{			in >> symbol;					operations.push(symbol);			cout<< "First Symbol " << symbol << endl;					}						else if(in.peek() == RIGHT_PARENTHESIS)		{			in.ignore();			do_operation(symbol, numbers, okay);		}			else			in.ignore();	}	return numbers.top();}
I think the best way to figure this out is to run the code in a debugger and see what it's actually doing. I believe Visual C++ Express to be a good IDE with a well-integrated debugger. Superpig wrote a nice article on debugging, too.

I don't know exactly what you mean when you say it doesn't get past the first if statement. Does it continually find LEFT_PARENTHESIS? Does it mysteriously stop?
Hi again,
I figured out the bug from the above code - my command line was waiting for user input. Having got that, the following code runs but it is outputting strange values. Like instead of simply evaluating 2+3 ... somewhere the output is being corrupted to output values in the range of 48 (when I type: 0+0) to 53 (2+3). There is a bit of code that may be involved so I am posting the full program.
Any help would be great.

// CP2001 - 2007// Assignment 1// Write a simple calculator program that takes as input an infix expression, // and outputs the equivalent postfix expression and the evaluation of the infix expression. // Assume that the input may contain (floating) numbers, arithmetic operations +,-,*, and /, // as well as parentheses. However, the expression need not b e fully parenthesized, // and when parentheses are missing, the usual C++ precedence rules are used to determine the order of evaluation. // When an invalid infix expression is entered, then an error message will be printed and the user will // be re-prompted to enter a new infix expression. The program will continue until the user type ENTER ('\n') without expressions. #include <cctype>     // Provides isdigit#include <cstdlib>    // Provides EXIT_SUCCESS#include <cstring>    // Provides strchr#include <iostream>   // Provides cout, cin, peek, ignore#include <stack>      // Provides the stack template class#include <string>using namespace std;// PROTOTYPES for functions used by this demonstration program:void do_operation(char operation, stack<double>& numbers, bool& okay);double evaluate_expression(string &postfix, bool& okay);void convert(string& infix, string& postfix);bool is_operand(char ch);bool takes_precedence(char operatorA, char operatorB);int main( ){	double answer;	bool okay;	do{		string infix;		string postfix;		cout << "================================================================" << endl;		cout << "Type an infix arithmetic expression (Just type ENTER to quit!!):" << endl;		cout << "Infix: ";		cin >> infix;		convert(infix, postfix);				cout << "Postfix: " << postfix << endl;		cout<< "you have gone past postfix" << endl;		answer = evaluate_expression(postfix, okay);		if(okay)			cout << "Evaluation: " << answer << "." << endl;		else			cout << endl << "Invalid infix notation!!" << endl;	}while(true);	system("pause");    return EXIT_SUCCESS;}double evaluate_expression(string& postfix, bool& okay)// Process each line for infix-to-postfix conversion and evaluation {	const char DECIMAL = '.';	const char LEFT_PARENTHESIS = '(';	const char RIGHT_PARENTHESIS = ')';		stack<double> numbers;	stack<char> operations;	double number;	char symbol;	char hold;	cout << "inside" << endl;	for(int i = 0; i < postfix.size(); i++)	{		hold = postfix;				if(isdigit(postfix) || (postfix == DECIMAL))		{			number = hold;				numbers.push(number);			cout<< "First Number " << numbers.top() << endl;		}		else if(strchr("+-*/", postfix))		{			symbol = hold;					operations.push(symbol);			cout<< "First Symbol " << symbol << endl;		}						else if(postfix == '\n')		{			cin.ignore();			do_operation(symbol, numbers, okay);		}				else			okay = !okay;	}	return numbers.top();}void do_operation(char operation, stack<double>& numbers, bool& okay)// Pops two numbers from s, applies the operation, and pushes the answer// back on the stack s. Sets okay to false if any errors are found,// but leaves okay alone if there are no errors.{	double operand1;	double operand2;		operand2 = numbers.top();	numbers.pop();	operand1 = numbers.top();	numbers.pop();	switch(operation)	{		case '+': 	numbers.push(operand1 + operand2);				break;		case '-': 	numbers.push(operand1 - operand2);				break;		case '*': 	numbers.push(operand1 * operand2);				break;		case '/': 	numbers.push(operand1 / operand2);				break;		default:	okay = !okay;	}}bool is_operand(char ch){	if(((ch >= 'a') && (ch <= 'z')) || ((ch >= 'A') && (ch <= 'Z')) || ((ch >= '0') && (ch <= '9')))		return true;	else		return false;}bool takes_precedence(char operatorA, char operatorB){	if(operatorA == '(')		return false;	else if(operatorB == '(')		return false;	else if(operatorB == ')')		return true;	else if((operatorA == '^') && (operatorB == '^'))		return false;	else if(operatorA == '^')		return true;	else if(operatorB =='^')		return false;	else if((operatorA == '*') || (operatorA == '/'))		return true;	else if((operatorB == '*') || (operatorB == '/'))		return false;	else		return true;}void convert(string& infix, string& postfix){	stack<char> hold_symbol;	char top_symbol;	char symbol;		for(int i = 0; i < infix.size(); ++i)	{		symbol = infix;		if(is_operand(symbol))			postfix = postfix + symbol;		else		{			while((!hold_symbol.empty()) && (takes_precedence(hold_symbol.top(), symbol)))			{				top_symbol = hold_symbol.top();				hold_symbol.pop();				postfix = postfix + top_symbol;			}			if((!hold_symbol.empty()) && (symbol == ')'))				hold_symbol.pop();			else				hold_symbol.push(symbol);		}	}	while(!hold_symbol.empty())	{		top_symbol = hold_symbol.top();		hold_symbol.pop();		postfix = postfix + top_symbol;	}}


Again, thanks for any info...
Thanks sirGustav,
Sorry, but im not sure what you mean, is that just a test? or an example of changes to the code?
Hi Again - In my screen swapping i seem to have lost the last message posted by sirGustav. If you are still there, could you re-post it???? is there any reason why the last few posts would dissappear from the forum??
Maybe he deleted it. Probably because we're not supposed to help with homework questions.
as MrEvil said

This topic is closed to new replies.

Advertisement