954,504 Members — Technology Publication meets Social Media
Username:
Password:
Lost login information?
Have something to say? Contribute New Article Reply to this Article

Need help with a recursive postfix expression evaluator

Hello all. I am a CS major and I am learning recursion right now and have a lab assignment to write a program that uses recursion to evaluate post fix expressions. I have made an attempt at this but I am stuck and need some help. Here is what I have so far. I started by writing a function that took a simple expression in ex(24+) and output an answer(6). Now to make it recursive to evaluate more complex expressions. I have made it work part way. For instance if you input 2*(6+4) as 264+* you get an output of 10. So I feel I am headed in the right direction as it should first evaluate (6+4) and it gets that right but now I can't figure out how to make it do the next step. Any help is appreciated.

Here is code....

int postfix(string s){
	cout<<s<<endl; // for debug
	int a, b;
	if (s.length() == 3 && !isdigit(s[s.length()-1] && isdigit(s[s.length()-2]))){
		cout<<s<<endl; // for debug
		a = s[0]-48;
		b = s[1]-48;
		cout<<"eval "<<a<<" "<<s[2]<<" "<<b<<endl;
		switch (s[2]) {
			case '+':
				return a + b;
			case '-':
				return a - b;
			case '*':
				return a * b;
			case '/':
				return a / b;
			default :
				cout<<"bad input\n";
			}
	} else {
			return postfix(s.substr(1,s.length()-2));
	}
	return 0; // This return is for debug
}

Here is sample output....
Enter postfix expression: 264+*
264+*
64+
64+
eval 6 + 4
264+* = 10.

00Vic
Newbie Poster
18 posts since Feb 2009
Reputation Points: 10
Solved Threads: 0
 

I have little bit modified your code and it is working. The only drawback is that it cannot handle more than one digit nos. at any point of time during calculation.
I have commented the code and am sure that you will understand it.
Though, I will explain it completely in a short while.

#include<iostream>
#include<string>
#include<sstream>
using namespace std;
//stringify just converts a int to string
inline string stringify(double x)
{
    ostringstream o;
    if (!(o << x))
        cout<<"Stringify::Bad Conversion";
    return o.str();
}

int postfix(string s)
{
    cout<<"New Postfix:"<<s<<endl; // for debug
    int a, b;
    if (s.length() == 3 && !isdigit(s[s.length()-1] && isdigit(s[s.length()-2])))
    {
        cout<<"Inside If:"<<endl; // for debug
        a = s[0]-48;
        b = s[1]-48;
        cout<<"eval "<<a<<" "<<s[2]<<" "<<b<<endl;
        switch (s[2])
        {
        case '+':

            return a + b;
        case '-':
            return a - b;
        case '*':
            return a * b;
        case '/':
            return a / b;
        default :
            cout<<"bad input\n";
        }
    }
    else
    {
        cout<<"theElsepart:"<<s.substr(1,3)<<endl;//ForDebugging
        //This needs explaination:
        //Lets say the the expression was "262/3*+"
        //Now, I am replacing the "62/" to its value by
        //calling postfix() again on "62/"

        return postfix(s.replace(1,3,stringify(postfix(s.substr(1,3)))));
    }
    return 0; // This return is for debug
}
int main()
{
    cout<<postfix("263+*");
}
siddhant3s
Practically a Posting Shark
816 posts since Oct 2007
Reputation Points: 1,486
Solved Threads: 140
 

Ignore the above post please.

Postfix notation is evaluated from left to right.
What your algo was: if say the expression is 22/2+1+, you were calculating 2/2+1 first. which ofcourse dont make any sense.
Rather you should calculate 22/ first and then replace it in the main expression by its value(which is 1).

So, here is your code with few modification. Comments has been added. If you need more explanation, reply here. The only draw back is that at no point of time, the value of any expression exceed one digit.

#include<iostream>
#include<string>
#include<sstream>
using namespace std;
//stringify just converts a int to string
inline string stringify(double x)
{
    ostringstream o;
    if (!(o << x))
        cout<<"Stringify::Bad Conversion";
    return o.str();
}

int postfix(string s)
{
    cout<<"New Postfix:"<<s<<endl; // for debug
    int a, b;
    if ( !isdigit(s[2]) && isdigit(s[0]))//check if the first three charactrs can be evaluated
    {
        //now if the length is greater than three, replace the first three with the value
        if (s.length() > 3 )
            return postfix(s.replace(0,3,stringify(postfix(s.substr(0,3)))));
        else if (s.length()==3)//elseif the length is 3
        {
            
            cout<<"Inside If:"<<endl; // for debug
            a = s[0]-48;
            b = s[1]-48;
            cout<<"eval "<<a<<" "<<s[2]<<" "<<b<<endl;
            switch (s[2])
            {
            case '+':

                return a + b;
            case '-':
                return a - b;
            case '*':
                return a * b;
            case '/':
                return a / b;
            default :
                cout<<"bad input\n";

            }
        }
        else //just a error check in case ;)
            cout<<"Too short to evaluate(min is 3)";

    }

    else
    {
        cout<<"theElsepart:"<<s.substr(1,3)<<endl;//ForDebugging
        //This needs explaination:
        //Lets say the the expression was "262/3*+"
        //Now, I am replacing the "62/" to its value by
        //calling postfix() again on "62/"

        return postfix(s.replace(1,3,stringify(postfix(s.substr(1,3)))));
    }
    return 0; // This return is for debug
}
int main()
{
    cout<<postfix("22/2+1+");
}
siddhant3s
Practically a Posting Shark
816 posts since Oct 2007
Reputation Points: 1,486
Solved Threads: 140
 
The only draw back is that at no point of time, the value of any expression exceed one digit.

unfortunately then it would fail to evaluate his original expression of
264+* ...right?

Agni
Practically a Master Poster
655 posts since Dec 2007
Reputation Points: 431
Solved Threads: 116
 

Yes, of course.
But I cannot help it. My job was to modify his code, not write it.
This catch is even in his original code so I cannot help. If he shows some efforts regarding multi-digits evaluation, I will surely help.
Using stack was a good idea to target such issue but then, he want it do recursively.:icon_smile:

siddhant3s
Practically a Posting Shark
816 posts since Oct 2007
Reputation Points: 1,486
Solved Threads: 140
 

Thanks to everyone for input. It is appreciated. I do not understand some of the things you guys are talking about. I am in a relatively early learning stage. I don't know what a stack is and I am using recursion because that's what the assignment is.

"For this lab assignment, you need to write a program that reads a postfix arithmetic expression (assuming that all operands in this expression are single-digit positive integers), and uses a recursive function to evaluate the expression and print out the result. "

Anyway I gave this alot of thought today and realized I need to store the numbers somewhere for complicated equations. So I have put my function in a class to make it easier for each recursion to access an array and counter. This is what I came up with...
(Please excuse all of the debug couts. They will be removed before project is submitted)

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

# define MAX_SIZE 50

class Calculator{
public:
	Calculator(); // default constructor
	int postfix(string s); // recursive function for evaluating postfix equations
private:
	int index;
	int the_array[MAX_SIZE];
};

int main(){
	Calculator eval;
	int choice, sum;
	bool quit = false;
	string pf_eq = "912+/";
	cout<<"This program will take a postfix expression as input, evaluate it, then output the result.\n";
	do {
		cout<<"\nMake selection\n";
		cout<<"1 Evaluate a postfix expression\n";
		cout<<"2 Quit\n";
		cin>>choice;

		switch (choice){
			case 1:
				cout<<"Enter postfix expression: ";
				cin.clear();
				cin>>pf_eq;
				cout<<pf_eq<<" = "<<eval.postfix(pf_eq)<<".\n";
				break;
			case 2:
				cout<<"Thanks for using the postfix evaluation program!\n";
				quit = true;
				break;
			default:
				cout<<"Please make a valid selection!\n";
		}
	} while (!quit);

}

Calculator::Calculator(){ // default constructor
	index = 0;
}

int Calculator::postfix(string s){
	cout<<"eval = "<<s<<endl;
	int a, b;
	if (s.length() == 0 ){
		index = 0;
		return the_array[0];
	} else if (isdigit(s[0])){
		cout<<"storing "<<s[0]<<" to index "<<index<<endl;
		the_array[index] = s[0]-48;
		index++;
		return postfix(s.substr(1,s.length()-1));
	} else {
		a = the_array[index-2];
		b = the_array[index-1];
		switch (s[0]) {
			case '+':
				cout<<" should be "<<a<<" "<<s[0]<<" "<<b<<endl;
				cout<<"replacing "<<the_array[index-2]<<" at index "<<index-2<<"with "<<a + b<<endl;
				the_array[index-2] = a + b;
				cout<<"Array index "<<index-2<<" is "<<the_array[index-2]<<endl;
				break;
			case '-':
				cout<<" should be "<<a<<" "<<s[0]<<" "<<b<<endl;
				cout<<"replacing "<<the_array[index-2]<<" at index "<<index-2<<"with "<<a + b<<endl;
				the_array[index-2] = a - b;
				cout<<"Array index "<<index-2<<" is "<<the_array[index-2]<<endl;
				break;
			case '*':
				cout<<" should be "<<a<<" "<<s[0]<<" "<<b<<endl;
				cout<<"replacing "<<the_array[index-2]<<" at index "<<index-2<<"with "<<a + b<<endl;
				the_array[index-2] = a * b;
				cout<<"Array index "<<index-2<<" is "<<the_array[index-2]<<endl;
				break;
			case '/':
				cout<<" should be "<<a<<" "<<s[0]<<" "<<b<<endl;
				cout<<"replacing "<<the_array[index-2]<<" at index "<<index-2<<"with "<<a + b<<endl;
				the_array[index-2] = a / b;
				cout<<"Array index "<<index-2<<" is "<<the_array[index-2]<<endl;
				break;
			default :
				cout<<"bad input\n";
			}
		index = index-1;
		cout<<"index is now "<<index<<endl;
		return postfix(s.substr(1,s.length()-1));
	}
	return the_array[0];
}

This seems to work fine and will evaluate long equations fine but now I am stuck on the last part of the lab. We were given examples of what the program should output when running and the last one looks like this.
C:\CSC191\Lab\06.recursion>lab6
Enter a postfix expression: 235-*11-/
Invalid divisor.

The problem with that equation is it ends up to be -4/0. I know I could have the function cout the Invalid divisor message but what about the int the function expects to return and also if I put this equation in my program it gets all the way to -4/0 then it hangs up and I can't figure this out. Below is my output. Thanks for any help offered.


This program will take a postfix expression as input, evaluate it, then output the result.

Make selection
1 Evaluate a postfix expression
2 Quit
1
Enter postfix expression: 235-*11-/
eval = 235-*11-/
storing 2 to index 0
eval = 35-*11-/
storing 3 to index 1
eval = 5-*11-/
storing 5 to index 2
eval = -*11-/
should be 3 - 5
replacing 3 at index 1with 8
Array index 1 is -2
index is now 2
eval = *11-/
should be 2 * -2
replacing 2 at index 0with 0
Array index 0 is -4
index is now 1
eval = 11-/
storing 1 to index 1
eval = 1-/
storing 1 to index 2
eval = -/
should be 1 - 1
replacing 1 at index 1with 2
Array index 1 is 0
index is now 2
eval = /
should be -4 / 0
replacing -4 at index 0with -4
Press any key to continue . . .

00Vic
Newbie Poster
18 posts since Feb 2009
Reputation Points: 10
Solved Threads: 0
 

>I do not understand some of the things you guys are talking about
I was talking about stack, which is in a way, exactly what you have done.
Stacks can be thought of as an array in which the last item which goes in will be the last item which comes out. It is more or less the same thing which you have done.

Mind you, I have not read your code.

Regarding your error handling mechanism you have various method:
1.The very best is to use exeptions, They are error handling mechanism of C++. Research about them. Its good to start using them.
2. cout a error and quite the program by using exit(1)[defined under <cstdlib>]. This will cause termination of the program.

I prefer you opt choice 1. and learn about exceptions. After you know about exceptions, you can read the following article about Detecting and responding to division by zero http://www.deitel.com/articles/cplusplus_tutorials/20060325/

siddhant3s
Practically a Posting Shark
816 posts since Oct 2007
Reputation Points: 1,486
Solved Threads: 140
 

Thanks. I will look into exception handling. The only other thing I was thinking to fix this would be to change my return type to a string and output results that way or changing it to a void that just couts everything; although I haven't had a chance to try either yet and I don't know if they would work for recursion. I will look into exception handling then maybe I can make it work without rewriting or substantially modifying the function again.

00Vic
Newbie Poster
18 posts since Feb 2009
Reputation Points: 10
Solved Threads: 0
 

Returning by string means that you will again have to convert each value you get to integers(although, you can always define a inline function for that like I did). But this was the best method provided exceptions were not invented. Returning by void will be a crime.
Doing things without exception handling will be like following the I-dont-want-to-learn-new-things-but-screw-the-old-one way.
But a slight caution: exceptions are also a good way to make your code unportable in a sense that not most of people(who will study your code) will not catch your exceptions; That bothers you if you were designing a library.
So be sure to issue a exit(1) just after you throw an exception. These thing would make sense when you read about exception handling

Wish you luck!!

siddhant3s
Practically a Posting Shark
816 posts since Oct 2007
Reputation Points: 1,486
Solved Threads: 140
 

I am reading about exceptions right now and have a few questions.
1) I think I understand. For example in my function the part of my switch that handles division would look like.......

case '/':
	try{
		if (b == 0){
			throw 0;
		}
	}			
return a / b;

now I need to have a catch function

catch (int x){
	if (x == 0)
		cerr<<"Invalid division by zero in equation\n";
}


2) Is this correct?
3) Does catch need to be a member of my class or would this be a global thing. (I don't exactly know where to put this in my code.)
4)Do I still need exit(1) somewhere? Ideally I would like it to deliver my error message then return to the menu instead of exiting the program if possible.

00Vic
Newbie Poster
18 posts since Feb 2009
Reputation Points: 10
Solved Threads: 0
 

also is returning by void a crime because it is bad practice or because it would not work?

00Vic
Newbie Poster
18 posts since Feb 2009
Reputation Points: 10
Solved Threads: 0
 

Hmm,
>For example in my function the part of my switch that handles division would look like.......
Well, it is not looking good!.
The try block should be in the code which runs your function i.e. the main()
The general layout should be like this

{
//inside your evaluative function
case '/':
    if (b == 0)
    {
        throw 0;
        exit(0);//in case someone don't catch your exception
    }
    return a / b;
    ....
    ...
    ....
    ....
//end of your evaluative function
}


int main()
{

    while (1)
    {
        try
        {
             //do all the input output code here,
             //
             //
            break;//this will get you out of the loop if no exception is thrown
        }
     catch (int i)
    {
        if (i==0)
            cout<<"Error! div by zero";
    }
//flow returns here when a exception is thrown
//thus get back to the start of the loop again
 }//ending while(1)

}

>Does catch need to be a member of my class or would this be a global thing. (I don't exactly know where to put this in my code.)
catch{} is a global thing, should be put just after the try{} block

>Do I still need exit(1) somewhere? Ideally I would like it to deliver my error message then return to the menu instead of exiting the program if possible.
Useexit(1) just after you throw the exception. This will ensure that your program at least terminates(rather than screwing your machine resources) if the exception has not been handled. Although, my compiler (g++)r print a error message if the exceptions are thrown but not catched. But then, it is implementation dependent. So it is better to put a exit(1);

>also is returning by void a crime because it is bad practice or because it would >not work?
I exclaimed that it is a crime in your case as it would imply that you will have to cout everything in the evaluative function, which is bad.

>Ideally I would like it to deliver my error message then return to the menu instead of exiting the program if possible.
Yes, the code segment I gave will do exactly the same thing. Lets see how:
If the exception is not encountered any function inside the try block, the program will eventually meet the break; statement and thus the outer while loop will terminate. If the exception is catched, the program flow returns to the end of the catch{} block hence the Loop starts again.

siddhant3s
Practically a Posting Shark
816 posts since Oct 2007
Reputation Points: 1,486
Solved Threads: 140
 

Thanks for all your help. It is appreciated. I am looking over you post to see if my code can still be improved, but I actually came back here to post that I had figured how how to make this work in a bit of a convoluted way. It does use an exception though. I also added a bool bad_divisor variable to my class that main() uses to determine whether or not to show the results of function. I am pasting code below. As I said it does fully work but I am still open to suggestions that may make it better or more efficient. Thanks again for all you help:)

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

# define MAX_SIZE 50

class Calculator{
public:
	Calculator(); // default constructor
	int postfix(string s); // recursive function for evaluating postfix equations
	bool get_bad_divisor(); // Check to see if eq had division by 0
	void reset_bad_divisor(); // resets bad_divisor flag after each eq for next one
private:
	int index; // Keeps current place of last stored number in array
	int the_array[MAX_SIZE]; //Array for storing ints from equation until operator is found
	bool bad_divisor; // Flag to check if eq had Division by 0
};

int main(){
	Calculator eval; // Insatnce of Calculator Class
	int choice, answer; // Menu selection variable
	bool quit = false; // When set to true stops menu loop
	string pf_eq = ""; // input string for equation
	cout<<"This program will take a postfix expression as input, evaluate it, then output the result.\n";
	do { // Menu Loop
		cout<<"\nMake selection\n";
		cout<<"1 Evaluate a postfix expression\n";
		cout<<"2 Quit\n";
		cin>>choice;

		switch (choice){ // Handle User selection
			case 1: // evaluate a postfix eq
				cout<<"Enter postfix expression: ";
				cin.clear();
				cin>>pf_eq;
				answer = eval.postfix(pf_eq);
				if (eval.get_bad_divisor()){
					cout<<"Please try another expression!\n";
					eval.reset_bad_divisor();
				} else {
					cout<<pf_eq<<" = "<<answer<<".\n";		
				}
				break;
			case 2: // quit program
				cout<<"Thanks for using the postfix evaluation program!\n";
				quit = true;
				break;
			default: // Invalid menu choice input
				cout<<"Please make a valid selection!\n";
		}
	} while (!quit); // End Menu Loop

}

Calculator::Calculator(){ // default constructor
	index = 0; // Set index to 0
	bad_divisor = false;
}
bool Calculator::get_bad_divisor(){ // Check to see if eq had division by 0
	return bad_divisor;
}
void Calculator::reset_bad_divisor(){ // resets bad_divisor flag after each eq for next one
	bad_divisor = false;
}

int Calculator::postfix(string s){ // recursive function for evaluating postfix equations
	//cout<<"eval = "<<s<<endl; // Debug cout
	int a, b; // Variables for the two ints currently being operated on
	if (s.length() == 0 ){
		index = 0;
		return the_array[0];
	} else if (isdigit(s[0])){
		//cout<<"storing "<<s[0]<<" to index "<<index<<endl;  // Debug cout
		the_array[index] = s[0]-48;
		index++;
		return postfix(s.substr(1,s.length()-1));
	} else {
		a = the_array[index-2]; // Get last 2 stored digits
		b = the_array[index-1]; // Get last 2 stored digits
		switch (s[0]) {
			
			// Addition operator
			case '+':
				//cout<<" should be "<<a<<" "<<s[0]<<" "<<b<<endl; // Debug cout
				//cout<<"replacing "<<the_array[index-2]<<" at index "<<index-2<<"with "<<a + b<<endl; // Debug cout
				the_array[index-2] = a + b; // Perform operation and store result in index of a
				//cout<<"Array index "<<index-2<<" is "<<the_array[index-2]<<endl; // Debug cout
				break;
			
			// Subtraction operator
			case '-':
				//cout<<" should be "<<a<<" "<<s[0]<<" "<<b<<endl; // Debug cout
				//cout<<"replacing "<<the_array[index-2]<<" at index "<<index-2<<"with "<<a - b<<endl; // Debug cout
				the_array[index-2] = a - b; // Perform operation and store result in index of a
				//cout<<"Array index "<<index-2<<" is "<<the_array[index-2]<<endl; // Debug cout
				break;
			
			// Multiplication operator
			case '*':
				//cout<<" should be "<<a<<" "<<s[0]<<" "<<b<<endl; // Debug cout
				//cout<<"replacing "<<the_array[index-2]<<" at index "<<index-2<<"with "<<a * b<<endl; // Debug cout
				the_array[index-2] = a * b; // Perform operation and store result in index of a
				//cout<<"Array index "<<index-2<<" is "<<the_array[index-2]<<endl; // Debug cout
				break;
			
			// Division operator
			case '/':
				//cout<<" should be "<<a<<" "<<s[0]<<" "<<b<<endl; // Debug cout
				//cout<<"replacing "<<the_array[index-2]<<" at index "<<index-2<<"with "<<a / b<<endl; // Debug cout
				//if (b == 0)
				//	cout<<"Equation contains illegal division by 0. This Program will now crash and burn!!!!!!!!!!!!\n"; // invalid division by 0
				try {
					if (b == 0){
						throw 0;
					} else {
						the_array[index-2] = a / b; // Perform operation and store result in index of a
					}
				}
				catch (int x){
					if (x == 0)
						bad_divisor = true;
						cerr<<"Equation contains illegal division by 0.\n";
				}
				//the_array[index-2] = a / b; // Perform operation and store result in index of a
				//cout<<"Array index "<<index-2<<" is "<<the_array[index-2]<<endl; // Debug cout
				break;
			default :
				cout<<"bad input\n";
			}
		index = index-1;
		//cout<<"index is now "<<index<<endl; // Debug cout
		return postfix(s.substr(1,s.length()-1));
	}
	return the_array[0];
}
00Vic
Newbie Poster
18 posts since Feb 2009
Reputation Points: 10
Solved Threads: 0
 

>It does use an exception though.
But it is not using the way it should. I guess my last post was of no use.
Do you know why exceptions were invented? To avoid checking the return value of each function for errors. And look what you are doing. You are still checking if(eval.get_bad_divisor()) in you main().So what is the point in using exceptions. And moreover, you are using the try-catch block inside the definition of a function that throws the exception.
I think you should read my last post again.
Well, I don't mind if you use the old return-value check approach, but then, please don't use (flawed) exception handling mechanism for just the sake of using it.

Another point: dont use #define MAX_SIZE 50
use const int MAX_SIZE=50; instead. Here is why: http://www.parashift.com/c++-faq-lite/newbie.html#faq-29.7

I hope you understand my point about exceptions. Here is a good tut for you: http://www.ozzu.com/cpp-tutorials/tutorial-exceptions-t86515.html

siddhant3s
Practically a Posting Shark
816 posts since Oct 2007
Reputation Points: 1,486
Solved Threads: 140
 

I had already written the code I posted before your last post. I am looking at how to incorporate your suggestions into my code now. I did not use the exception just to use it. I used it to stop the program from crashing on division by 0. This was the only way I could figure out how to use it at the time. I don't understand your complaint about using it inside the function. The division by 0 happens inside the function so I thought this was the logical place to put it. I am just learning about exceptions for the first time today and I have not learned many advanced c++ programming concepts yet. Before recursion the most advanced thing were were taught is classes, functions, basic input and output, loops, and arrays. I appreciate your help but these are complicated concepts when you first start to learn them, and don't get me started on how little help my instructor is. Please keep offering help, but also please be patient with me I am just learning. At least I am trying to do this myself so I learn something and I didn't come looking for free homework answers.

00Vic
Newbie Poster
18 posts since Feb 2009
Reputation Points: 10
Solved Threads: 0
 

>>I don't understand your complaint about using it inside the function
Ok, I am rather guilty, fine?
So, I think I would need to explain it further.
Look, You should throw an exception whenever you encounter a error in any piece of your code by using throw anumber whenever you encounter a error. But, use the try-catch block in the calling code of the function. Not when throwing exception. Getting it?
In short, you should write the try-catch block in main() and not in postfix(). Got it?
You should issue a throw 0 in postfix but catch it in main()
Phew!

siddhant3s
Practically a Posting Shark
816 posts since Oct 2007
Reputation Points: 1,486
Solved Threads: 140
 

That makes some sense but I thought the catch needed to be placed just after the try in the code.

00Vic
Newbie Poster
18 posts since Feb 2009
Reputation Points: 10
Solved Threads: 0
 

>That makes some sense but I thought the catch needed to be placed just after the >try in the code.
Yes you are right. So that what I said:

.
.
.
{//in post fix
    if (somecondition)
        throw 0;//look, i hv not used any try{}
    .
    .
    .
}//end of postfix


int main()
{
    while (1)
    {
        try//here i use try
        {
//somecode
            postfix();
            break;
        }
        catch (int i)//and catch just after try{}
        {
            if (i==0)
                cout<<"Erorror";
        }
    }
}
siddhant3s
Practically a Posting Shark
816 posts since Oct 2007
Reputation Points: 1,486
Solved Threads: 140
 

Okay I see. I thought the throw had to come from inside a try. I did not realize it could be used elsewhere. then in main() it looks something like this....

case 1: // evaluate a postfix eq
	cout<<"Enter postfix expression: ";
	cin.clear();
	cin>>pf_eq;
	answer = eval.postfix(pf_eq);
	try{
		if (eval.get_bad_divisor()){
			throw 1;
		} else {
			cout<<pf_eq<<" = "<<answer<<".\n";
		}
	catch (int q){
		if (q == 1){
			cout<<"Invalid division by 0 in expression!\n";
			eval.reset_bad_divisor();
		}
	} 
	break;
00Vic
Newbie Poster
18 posts since Feb 2009
Reputation Points: 10
Solved Threads: 0
 

Better, but Still not got it!
No problem. I will try to explain again:
See, the whole story of exception is to eradicate the need for checking anything in main() as you are doing

try{
		if (eval.get_bad_divisor()){ //<<<to eradicate this
			throw 1;
		} else {
			cout<<pf_eq<<" = "<<answer<<".\n";
		}

So now, you have already thrown a exception while dealing with postfix(), right?
I mean, you have already thrown the exception in the postfix() function, so you don't need to throw it again in main()[and neither there is need to check if (eval.get_bad_divisor()) ]
First of all, try{} block should contain all those function call which can potentially throw an exception. In your case it is postfix(). So you should include the postfix() in the try block. Now the code should appear like this:

case 1: // evaluate a postfix eq
	cout<<"Enter postfix expression: ";
	cin.clear();
	cin>>pf_eq;
             try{
		answer = eval.postfix(pf_eq);
		}
              catch (int q){
		if (q == 1){
			cout<<"Invalid division by !\n";
		         }
		}
             break;
//rest of your code..........

		}

Lets see what will happen in the above code:
You are calling postfix() in a try block, right? So, either two things can happen:
1.The postfix() don't encounter any div-zero error: In this case, no exception will be thrown by postfix() hence the try block will be executed fully and the control will return directly to Line13 (overlooking the catch{})
2.If postfix() emits a exception, the control will be (no matter where it was earlier) directly passed to the catch block at Line9 and will issue a error and continue from Line13

After Line13, your program will run as usual. So no need of the ugly eval.get_bad_divisor()

Got it?

siddhant3s
Practically a Posting Shark
816 posts since Oct 2007
Reputation Points: 1,486
Solved Threads: 140
 

This question has already been solved

Post: Markdown Syntax: Formatting Help
You