Infix to postfix C++

Hey, I'm trying to write a program that reads an infix expression from a file, converts it to postfix, and prints it out.  I am probably at least 70% done but am stuck on a few key things:
1)Making sure my constructor is serving it's purpose, not sure why it is supposed to have an arg
2)printing my posfix and infix correctly
3)setting up my main() correctly

If someone could just run through these things to get me un-stuck I'd appreciate it.  Also, I havn't had a chance to check my logic in my actual convert method because I havn't been able to print anything yet.  It only prints nonsense.  That's why the more complicated parts are commented out.  Heres the code:



// Specification file for InfixToPostfix.h

#ifndef H_InfixToPostfix
#define H_InfixToPostfix
#include <iostream>
#include <string>
#include <stack>

using namespace std;

class infixToPostfix
{
public:
	void convertToPostfix();
	bool precedence(char newop, char old);
	void getInfix(string);
	void showInfix();
	void showPostfix();
	infixToPostfix(string = ""); //Default constructor
		
private:
	string  ifx;
	string  pfx;
};

infixToPostfix::infixToPostfix(string rtIfx)
{
ifx = rtIfx;
}
void infixToPostfix::getInfix(string a)
{
ifx = a;
}
void infixToPostfix::showPostfix()
{
cout << pfx;
}
void infixToPostfix::showInfix()
{
cout << ifx;
}
void infixToPostfix::convertToPostfix()
{
string postfixString;
stack<char> optrStk;
char item;

for(int i = 0; i <= ifx.length(); i++)
{
	if(ifx[i] == '*' || ifx[i] == '/' || ifx[i] == '+' || ifx[i] == '-')
	{
		if(!optrStk.empty())
		{
			item = optrStk.top();
			if((precedence(ifx[i], item)) == true)
			optrStk.push(ifx[i]);
			else if((precedence(ifx[i], item)) == false)
			//cout << item;
			optrStk.pop();
			optrStk.push(ifx[i]);
		}
		if(optrStk.empty()== true)
		{
			optrStk.push(ifx.at(i));
		}
	}		
// 	else if(ifx[i] == '(')
// 	{
// 		optrStk.push(ifx[i]);		
// 	}
// 	else if(item == ')')
// 	{
// 		while(optrStk.top() != '(')
// 		{
// 		item = optrStk.top();
// 		optrStk.pop();
// 		cout << item;
// 		}
// 	optrStk.pop();
//	}			
	else
	{
		//cout << ifx[i];
	}
}
}
bool infixToPostfix::precedence(char newop, char old)
{
bool higher;
if(newop == '*' || newop == '/' && old == '+' || old == '-')
	higher = true;
else if(newop == '+' || newop == '-' && old == '*' || old == '/')
	higher = false;
else if(newop == '*' || newop== '/' && old == '*' || old == '/')
	higher = true;
else if(newop == '+' || newop == '-' && old == '+' || old == '-')
	higher = true;
return higher;
}
	


#endif

#include <iostream>
#include <fstream>
#include <string>
#include "infixToPostfix.h"

using namespace std;

int main()
{

	infixToPostfix  InfixExp;
	string infix;

	ifstream infile;

	infile.open("Data.txt");

	if(!infile)
	{
		cout<<"Cannot open input file. Program terminates!!!"<<endl;
		return 1;
	}
	else{
	getline(infile,infix);
	InfixExp.getInfix(infix);
	//InfixExp.showInfix();
	

	
	InfixExp.convertToPostfix();// perform conversion


	InfixExp.showPostfix();


	infile.close();
	}

	return 0;
}

Open in new window

v8forlyfeAsked:
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

lucky_jamesCommented:
your constructor and getinfix method are doing some common job (of course, your contructor os also used for object instantiation).

in place of :
   getline(infile,infix);
    InfixExp.getInfix(infix);
make it as:
        getline(infile,infix);
        infixToPostfix  InfixExp(infix);

or remove your argument from the contructor....

This answers your 1.
Regarding 2, what is that you wanna get....and whats is that you are getting right now?
Regarding 3, what do you mean by setting up main? please elaborate....

Hope it helps.
0
v8forlyfeAuthor Commented:
Hey thanks for the help so far, sorry for my vagueness.  I need to "get" the infix expression from the file and set it to ifx if that makes sense, and I'm not sure if that part is doing it's job or not, because it's printing out a bunch of binary crap.  Question marks, random jargon I don't understand, nothing from the actual file which only contains infix expressions.

And as far as my main goes, you answered part of that already, I just wanted to make sure my functions were being called correctly and were in the right order.
0
phoffricCommented:
1. If you do not know what the purpose of the argument to the constructor is, then why did you include an argument in the first place?
2. >> printing my posfix and infix correctly
3 >> setting up my main() correctly
Could you give specifics as to what is wrong?

>> I haven't had a chance to check my logic in my actual convert method because I haven't been able to print anything yet.  It only prints nonsense.
Maybe there is something wrong with your Data.txt file.

Did you write the posted code yourself? If so, then you probably know best which lines would be good to look at most closely. To do that, you can add cout statements to see at what point the "nonsense" begins to appear. An easier approach is to just step through the program with your debugger and check the values as they change from line to line.

If you have specific questions, just ask.

I did notice that getInfix() and your constructor are both setting ifx. Did you notice that?
0
Cloud Class® Course: Amazon Web Services - Basic

Are you thinking about creating an Amazon Web Services account for your business? Not sure where to start? In this course you’ll get an overview of the history of AWS and take a tour of their user interface.

phoffricCommented:
Oh, I didn't see the first post. Sorry about any redundancies.
0
v8forlyfeAuthor Commented:
It's alright.  I wrote 95% of the code from scratch, the other 5% was given to me as a starting point, hence the arg in the constructor that I don't quite know what to do with, but I think I've taken care of that problem.

I did step through the program, that's why blocks are commented out because the cause the error given in my first and second post.  The showInfix() in my main for instance prints out this kind of stuff "content.xml¿VmO¿0¿¿_e¿¿R" and I don't know why, that's the part I'm stuck at and that's why I posted, because I'm completely lost.


0
phoffricCommented:
what is in your input file?
The constructor argument can be used in lieu of an input file (e.g., "2 + 7 * 4")
line 71: else if(item == ')')
Where is item set?
0
v8forlyfeAuthor Commented:
my input file nomally has about 5 infix ops, but right now it is only as follows until I can get this debugged:
A+B-C

Good catch on the item thing, it is set only when it sees one of the first 4 operands.  I changed all cases of "item" with "ifx[i]" when checking for parenthesis, does that look like it would help?
0
phoffricCommented:
Not sure if I updated my code exactly as you did. (If doing changes, feel free to post again your latest code.)
For what you gave, A+B-C, the program prints out ABC, but I don't see all the garbage you were talking about. (nor are there operators). I don't see where you are printing out operators. Why not make changes to do this and re-post.
I'm leaving now for about 2 hours.
0
v8forlyfeAuthor Commented:
Ok thanks for the help so far, the debugging tip you gave me has helped a lot already.  I can now print out a correct postfix op!  I'll update after I get stuck again, but for now I can keep going on my own for a bit.
0
lucky_jamesCommented:
great!! do let us know in case you are stuck somewhere...
0
v8forlyfeAuthor Commented:
Hit a new obstacle.  Now that my program is working fine without parenthesis (had to find a few other bugs but those should be good now) I uncommented my part that deals with them.  Only problem is, when I try to run the program, it gives me a segmentation error.  Here's the code.  It is somewhere in that short segment.


else if(ifx[i] == '(')
	{
		optrStk.push(ifx[i]);		
	}
	else if(ifx[i] == ')')
	{
		while(optrStk.top() != '(')
		{
		item = optrStk.top();
		optrStk.pop();
		cout << item;
		}
	optrStk.pop();
	}

Open in new window

0
lucky_jamesCommented:
post your full code...
0
phoffricCommented:
Since I don't have all your code changes or your test code, I'll just give you these suggestions. In precedence() cout the input variables and see if they make sense. Then add an else statement and if you get there, then cout an error message and either exit or return some value for higher that might make sense for you.
0
lucky_jamesCommented:
I mean if its possible.....and also the input your are passing.
0
phoffricCommented:
In your posts, pfx is not being set; and then you print it out.

i <= ifx.length()
but indexes start at 0

re: binary operator precedence
A more general approach to use instead of difficult to read if statements is to use a square matrix whose entries are true/false. This allows for easy expansion to add other binary operators; and with good comments (headers for columns, and line comments for rows) should be easy to decipher.

0

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
phoffricCommented:
re: operator precedence
Another table driven approach is to define the attributes to include:
- number of operands (unary, binary, ternary)
- precedence (just an integer)
- associativity (LtoR or RtoL)
As you add more operators, the matrix becomes harder to maintain (works fine for the above 4x4 case).
You could use a multimap to hold the operator and its attributes.
0
v8forlyfeAuthor Commented:
I'm pretty sure my precedence method is working correctly now, if you input any infix without parenthesis (because that part is creating a segfault) it will output correctly.  In the commented part of the convert method, it is somewhere in the while loop i think.

Also, I still don't know why my file reader doesn't work, but I don't care about that as much right now.
// Specification file for InfixToPostfix.h

#ifndef H_InfixToPostfix
#define H_InfixToPostfix
#include <iostream>
#include <string>
#include <stack>

using namespace std;

class infixToPostfix
{
public:
	void convertToPostfix();
	bool precedence(char newop, char old);
	void getInfix(string);
	void showInfix();
	void showPostfix();
	infixToPostfix(string = ""); //Default constructor
		
private:
	string  ifx;
	string  pfx;
};

infixToPostfix::infixToPostfix(string rtIfx)
{
ifx = rtIfx;
}
void infixToPostfix::getInfix(string a)
{
ifx = a;
}
void infixToPostfix::showPostfix()
{
cout << pfx;
}
void infixToPostfix::showInfix()
{
cout << ifx;
}
void infixToPostfix::convertToPostfix()
{
string postfixString;
stack<char> optrStk;
char item;

for(int i = 0; i <= ifx.length(); i++)
{
	if(ifx[i] == '*' || ifx[i] == '/' || ifx[i] == '+' || ifx[i] == '-')
	{
		if(!optrStk.empty())
		{
			item = optrStk.top();
			if((precedence(ifx[i], item)) == true)
			{
			cout << item;
			optrStk.pop();
			optrStk.push(ifx[i]);
			}
			else if((precedence(ifx[i], item)) == false)
			optrStk.push(ifx[i]);
		}
		if(optrStk.empty())
		{
			optrStk.push(ifx[i]);
		}
	}	
// 	if(ifx[i] == '(')
// 	{
// 		optrStk.push(ifx[i]);		
// 	}
// 	if(ifx[i] == ')')
// 	{
// 		while(optrStk.top() != '(')
// 		{
// 		ifx[i] = optrStk.top();
// 		optrStk.pop();
// 		cout << item;
// 		}
// 	optrStk.pop();
// 	}			
	else
	{
		cout << ifx[i];
	}
	
}
while(!optrStk.empty())
{
item = optrStk.top();
cout << item;
optrStk.pop();
}
}
bool infixToPostfix::precedence(char newop, char old)
{
bool higher;
if((newop == '*' || newop == '/') && (old == '+' || old == '-'))
	higher = false;
else if((newop == '+' || newop == '-') && (old == '*' || old == '/'))
	higher = true;
else if((newop == '*' || newop== '/') && (old == '*' || old == '/'))
	higher = true;
else if((newop == '+' || newop == '-') && (old == '+' || old == '-'))
	higher = true;
return higher;
}
	


#endif

include <iostream>
#include <fstream>
#include <string>
#include "infixToPostfix.h"

using namespace std;

int main()
{

	
	string infix = "A*B+C";

	ifstream infile;

	infile.open("Data.txt");

	if(!infile)
	{
		cout<<"Cannot open input file. Program terminates!!!"<<endl;
		return 1;
	}
	else{
	//getline(infile,infix);
	infixToPostfix  InfixExp(infix); 
	InfixExp.showInfix();
	

	
	InfixExp.convertToPostfix();// perform conversion


	//InfixExp.showPostfix();


	infile.close();
	}

	return 0;
}

Open in new window

0
v8forlyfeAuthor Commented:
Oh, change the commented-out ifx[i] to item = optrStk.top(); otherwise it doesn't make sense.
0
phoffricCommented:
Output from below test driver..
Why a space in postfix expression?
First result is XY+Z- (removed space)
Letting X=A,  Y=B*C, Z=D*E*F, why isn't 3rd result of the same form as 1st result?
i.e., ABC*+Z-
==================
X+Y-Z
XY+Z -

D*E*F
DE*F *

A+B*C-D*E*F
ABC*DE*F *-+

X*Y+Z
XY*Z +

A*B*C+D*E*F
AB*C*DE*F *+

A+B*C
ABC *+

Z+A*B-C/D*E+F*G
ZAB*CD/E*FG *+-+

A+(B-C)
A(B+C) -
==================
void test(string str) {
   infixToPostfix  InfixExp1(str);
   InfixExp1.showInfix();
   InfixExp1.convertToPostfix();// perform conversion
   cout << endl << endl;
}
int main()
{
   test("X+Y-Z");
   test("D*E*F");
   test("A+B*C-D*E*F"); // X=A,  Y=B*C, Z=D*E*F

   test("X*Y+Z");
   test("A*B*C+D*E*F");

   test("A+B*C");
   test("Z+A*B-C/D*E+F*G");
   test("A+(B-C)");  
   return 0;
}

Open in new window

0
phoffricCommented:
>> Oh, change the commented-out ifx[i] to item = optrStk.top(); otherwise it doesn't make sense.
Maybe, never mind previous post. I didn't comment anything out.
What line should I comment out so that  we're in sync?
0
phoffricCommented:
In http:#29763660
I said:
    i <= ifx.length();
but indexes start at 0

You made no comment on this.
0
phoffricCommented:
From the interchange, it appears that I provided assistance that was used by the author.
0
phoffricCommented:
I recommend "Accept one or more Expert posts as the answer".

split: 3/4th for phoffric (180 points); 1/4th for lucky_james (70 points)
Accept: http:#29750309 (lucky_james)

Accept: http:#29751296
"An easier approach is to just step through the program with your debugger and check the values as they change from line to line."
  -- to which author says (http:#29754124): "Ok thanks for the help so far, the debugging tip you gave me has helped a lot already."

Accept: http:#29752708
"line 71: else if(item == ')')
 Where is item set?"
  -- to which author says (http:#29753175 ): "Good catch on the item thing"

Accept: http:#29763660
   pfx is not being set
   but indexes start at 0
0
v8forlyfeAuthor Commented:
alright, i'll do that, i fixed it when i redid all of my logic, so i didn't know who to give it to, i'll do what you said though!
0
phoffricCommented:
Ah, you started over for the better. That shows a lot of extra insight!
0
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
Editors IDEs

From novice to tech pro — start learning today.