i made a program to evaluate an expression, "expeval.cpp" [find attached].
i then tried to go further.....
i made the program to read characters from the keyboard and write it into a file["file.cpp",find attached]. if an expression is encountered, it is evaluated and the result is displayed after the line and also written into the file.
When the program encounters '==' the expression evaluation is initiated and when ';' is encountered, expression is terminated.
This, was working till i changed the input style. From gets to cin.get .

Then everything went wrong!
pls help me find wat went wrong!!!
:icon_confused:

Please..........i've got to submit the project within one week!!!:S

Recommended Answers

All 9 Replies

PROGRAM CODE OF "expeval.cpp"

#include<iostream.h>
#include<conio.h>
#include<stdio.h>
#include<process.h>
#include<ctype.h>


/**********************Definitions of Data Structures Used*********************/


union element
	{ char sym;
	  int ival;
	  float fval;
	};

struct info
	{	element el;
		char flag;
	};

class Queue
	{	struct node
		{       info inf;
			node *next;
		}*front,*rear;
	 public:
		Queue()
		{front=rear=NULL;}
		void push(info n);
		info pop();
		info peek()
		{return front->inf;}
	}expr;

class Stack
	{	struct node
		{       info inf;
			node *next;
		}*top;
	 public:
	       Stack()
	       {top=NULL;}
	       void push(info);
	       info pop();
	       info peek()
	       {return top->inf;}
	};

/******************************End of definitions******************************/


/***************************Function declarations******************************/
char symb( char);
void display(Queue);
int insert();
void post_convert();
int evaluate();
void expression();


/****************************End of declarations******************************/


/*******************************Main Function**********************************/
void main()
{	clrscr();
	expression();
	getch();
}

/********************************End of Main***********************************/


/************************Other Function definitions****************************/
void expression()
{	int fail=insert();

	if(fail==0)
	post_convert();

	fail=evaluate();
	if(fail)cout<<"Error in eval ";
	getch();
}


int insert()
{

	int ctr=0,sign=1;
	float factor;
	char in[81];
	info inf={ 0,0};	//INPUT is by default integer


	cin.getline(in,81);
	for(int i=0;in[i]!='\0';i++)
	{	if(in[i]==' ')continue;
		if(symb(in[i]))
		{
			if(in[i]=='-'&&(symb(in[i-1])||i==0)&&in[i-1]!=')')
							//If operator is unary
			{	sign=-1;		//minus, change sign of
				inf.flag=0;		//factor, set flag as
				continue;		//integer, and continue
			}
			else if(symb(in[i])&&symb(in[i+1]))
			  if(in[i+1]!='('&&in[i+1]!='-'&&in[i+1]!='\0'&&in[i]!=')')
			  {	cout<<"Error!! too many operators!!!";
				return -1;
			  }
			else
			  sign=1;
			if(in[i]=='(')
			{	ctr++;
				if(inf.flag!=2&&i!=0)	//If there is no symbol
				{	inf.el.sym='*';	//before '(', then
					inf.flag=2;	//multiply by default
					expr.push(inf);
				}
			}
			else if(in[i]==')')
			  ctr--;

			inf.flag=2;		//INPUT is a symbol(operator)
			inf.el.sym=in[i];
			expr.push(inf);

		}
		else if(isdigit(in[i]))
		{       if(symb(in[i-1])||i==0)
			{	inf.flag=0;		//reset flag
				inf.el.fval=0.0;	//reset el
				inf.el.ival=(int)(in[i]-'0')*sign;
			}
			else if(inf.flag)
			{	factor/=10;	//decrement the place value
						//of last digit
				inf.el.fval+=(in[i]-'0')*factor*sign;
			}
			else
			  inf.el.ival=10*inf.el.ival+(int)(in[i]-'0')*sign;

			if(symb(in[i+1])||in[i+1]=='\0')
			  expr.push(inf);
		}
		else if(in[i]=='.')
		{	inf.el.fval=(float)inf.el.ival;
			inf.flag=1;	//INPUT is float type

			factor=1;	//Reset the place value
					//of last digit added
			if(symb(in[i+1])||in[i+1]=='\0')
			  expr.push(inf);
		}
	}
	if(ctr>0)
	  while(ctr)
	  {	info inf={')',2};
		expr.push(inf);
		ctr--;
	  }

	else if(ctr<0)
	{	cout<<"Error!!! More right paranthesis!!!";
		return -1;
	}

	return 0;
}

char symb(char c)
{	switch(c)
	{ case '^':return 9;
	  case '/':return 8;
	  case '*':return 8;
	  case '+':return 7;
	  case '-':return 7;
	  case '(':return -1;
	  case ')':return 1;
	  default :return 0;
	}

}

void display(Queue exp)
{	info inf={0,0};
	while(inf.flag!=-5)
	{	inf=exp.pop();
		switch(inf.flag)
		{ case 0 :cout<<"\nInteger : "<<inf.el.ival;break;
		  case 1 :cout<<"\nFloat   : "<<inf.el.fval;break;
		  case 2 :cout<<"\nOperator: "<<inf.el.sym;break;
		  case -5:cout<<"\nEnd ofExpression";break;
		  default:cout<<"\nError in output";
		}
	}
}

void post_convert()
{	Queue temp;
	Stack symbols;
	info psym,pexp={'(',2};
	symbols.push(pexp);

	while(pexp.flag!=-5)
	{	pexp=expr.pop();
		if(pexp.flag==2)
		{	psym=symbols.peek();
			while((symb(psym.el.sym)>symb(pexp.el.sym))
							&&pexp.el.sym!='(')
			{	psym=symbols.pop();	//Push all operators of
				temp.push(psym);	//greater precedence
				psym=symbols.peek();	//into expr
			}
			if(pexp.el.sym==')')	//If the symbol is ')' , then
			  symbols.pop();	//remove '(' from the symbols
			else                    //Else push the symbol into
			  symbols.push(pexp);	//the symbols stack
		}
		else if(pexp.flag==-5)
		{	psym=symbols.pop();
			while(psym.el.sym!='(')
			{	temp.push(psym);
				psym=symbols.pop();
			}
		}
		else
		  temp.push(pexp);
	}
	expr=temp;

}

int evaluate()
{	Stack eval;
	info pexp,pnum,op1,op2,res;
	int ctr=0;
	pexp=expr.pop();
	do
	{       ctr++;
		if(pexp.flag==1||pexp.flag==0)  //if element is a number
		  eval.push(pexp);		//push into stack
		else if(pexp.flag==2)
		{ op2=eval.pop();
		  op1=eval.pop();
		  if(op1.flag||op2.flag)	//if op1 or op2 is float type
		    res.flag=1;			//the result is float
		  else if(op1.flag==-5)         //else if there is no element
		    cout<<"Too less operands";	//in stack, display error
		  else				//else
		    res.flag=0;			//the result is int type

		  switch(pexp.el.sym)
		  { case '+' :if(res.flag)
				res.el.fval=
				  (op1.flag?op1.el.fval:op1.el.ival)+
				      (op2.flag?op2.el.fval:op2.el.ival);
			      else
				res.el.ival=
				  (op1.flag?op1.el.fval:op1.el.ival)+
				      (op2.flag?op2.el.fval:op2.el.ival);
			      break;
		    case '-' :if(res.flag)
				res.el.fval=
				  (op1.flag?op1.el.fval:op1.el.ival)-
				      (op2.flag?op2.el.fval:op2.el.ival);
			      else
				res.el.ival=
				  (op1.flag?op1.el.fval:op1.el.ival)-
				      (op2.flag?op2.el.fval:op2.el.ival);
			      break;
		    case '*' :if(res.flag)
				res.el.fval=
				  (op1.flag?op1.el.fval:op1.el.ival)*
				      (op2.flag?op2.el.fval:op2.el.ival);
			      else
				res.el.ival=
				  (op1.flag?op1.el.fval:op1.el.ival)*
				      (op2.flag?op2.el.fval:op2.el.ival);
			      break;
		    case '/' :if(res.flag)
				res.el.fval=
				  (op1.flag?op1.el.fval:op1.el.ival)/
				      (op2.flag?op2.el.fval:op2.el.ival);
			      else
				res.el.ival=
				  (op1.flag?op1.el.fval:op1.el.ival)/
				      (op2.flag?op2.el.fval:op2.el.ival);
			      break;
		    default  :cout<<"\nError!!in eval"<<pexp.el.sym;return-1;
		  }
		  eval.push(res);
		}
		pexp=expr.pop();


	}while(pexp.flag!=-5);



	res=eval.pop();
	op1=eval.pop();

	if(op1.flag!=-5)
	  return -1;


	 cout<<"\nOUTPUT  : "<<(res.flag?res.el.fval:res.el.ival);

	return 0;


}

/*******************************End of Definitions****************************/


/***********************Definition of Queue class functions*******************/
void Queue::push(info n)
{       if(front==NULL)
	  front=rear=new node;
	else
	{	rear->next=new node;
		rear=rear->next;
	}

	if(rear==NULL)
	cout<<"Error cannot insert in Q";

	rear->inf=n;
}


info Queue::pop()
{	if(front==NULL)
	{	info temp={0,-5};
		return temp;
	}

	info temp=front->inf;
	node *temptr=front;
	if(front==rear) front=rear=NULL;
	else
	  front=front->next;
	delete temptr;

	return temp;
}


/*******************************End of Definitions****************************/


/*********************Function Definitions of Stack Class**********************/


void Stack::push(info n)
{	node* temp=new node;
	if(temp==NULL)
	{	cout<<"Cannot insert into stack!!!";
		return;
	}
	temp->inf=n;
	temp->next=top;
	top=temp;
}


info Stack::pop()
{	if(top==NULL)
	{	info temp={0,-5};
		return temp;
	}

	info n=top->inf;
	node* temp=top;
	top=top->next;
	delete 	temp;
	return n;
}



/********************************End of Definitions***************************/

PROGRAM CODE OF "file.cpp"

#include<fstream.h>
#include<conio.h>
#include<stdio.h>
#include<process.h>
#include<ctype.h>


/**********************Definitions of Data Structures Used*********************/


union element
	{ char sym;
	  int ival;
	  float fval;
	};

struct info
	{	element el;
		char flag;
	};

class Queue
	{	struct node
		{       info inf;
			node *next;
		}*front,*rear;
	 public:
		Queue()
		{front=rear=NULL;}
		void push(info n);
		info pop();
		info peek()
		{return front->inf;}
	};

class Stack
	{	struct node
		{       info inf;
			node *next;
		}*top;
	 public:
	       Stack()
	       {top=NULL;}
	       void push(info);
	       info pop();
	       info peek()
	       {return top->inf;}
	};

/******************************End of definitions******************************/



//Defining Global objects and variables
fstream temp;
Queue expr;
int exp_flag;


/***************************Function declarations******************************/
char symb( char);
void display(Queue);
int insert();
void post_convert();
int evaluate();
int expression();


/****************************End of declarations******************************/


/*******************************Main Function**********************************/
void main()
{	clrscr();
	temp.open("temp.mth",ios::out|ios::in);
	char ch;
	cin.get(ch);
	while(ch!=7)
	{	exp_flag=0;
		if(ch=='=')
		{	cin.get(ch);
			if(ch=='=')
			  exp_flag=expression();
			else
			  temp.put('=');
			if(exp_flag)
			  cout<<"Error : Expression syntax error!!";
		}
		else
		temp.put(ch);
		cin.get(ch);
	}

	getch();
}

/********************************End of Main***********************************/


/************************Other Function definitions****************************/
int expression()	//converts infix expression to postfix and evaluates
{       exp_flag=0;
	int fail=insert();
	cout<<"return frm insert()";

	if(fail)return -1;

	post_convert();
	cout<<"\nreturn from post_convert()";
	fail=evaluate();
	cout<<"\nreturn from evaluate()"<<fail;
	if(fail)
	{	char in[81];
		if(exp_flag==1)			//Remove input expression if
		  temp.getline(in,81,'\n');	//output failed

		return -1;
	}
	return 0;
}

int insert()			//insert into queue
{	int ctr=0,sign=1,MinusFlag=1;
	float factor;
	char in[81];
	info inf={ 0,0};	//INPUT is by default integer


	for(int i=0;i<81&&in[i-1]!=';';i++)
	{	cin.get(in[i]);
		if(isspace(in[i]))i--;
	}
	for(i=0;in[i]!=';';i++)
	{
		if(symb(in[i]))
		{
			if(in[i]=='-'&&MinusFlag)
							//If operator is unary
			{	sign=-1;		//minus, change sign of
				inf.flag=0;		//factor, set flag as
				continue;		//integer, and continue
			}
			else if(symb(in[i])&&symb(in[i+1]))
			  if(in[i+1]!='('&&in[i+1]!='-'&&in[i]!=')')
			  {	cout<<"Error!! too many operators!!!";
				return -1;
			  }
			else
			  sign=1;
			if(in[i]=='(')
			{	ctr++;
				if(inf.flag!=2&&i!=0)	//If there is no symbol
				{	inf.el.sym='*';	//before '(', then
					inf.flag=2;	//multiply by default
					expr.push(inf);
				}
			}
			else if(in[i]==')')
			  ctr--;

			if(in[i]=='-') MinusFlag=1;

			inf.flag=2;		//INPUT is a symbol(operator)
			inf.el.sym=in[i];
			expr.push(inf);

		}
		else if(isdigit(in[i]))
		{       if(symb(in[i-1])||i==0)
			{	inf.flag=0;		//reset flag
				inf.el.fval=0.0;	//reset el
				inf.el.ival=(int)(in[i]-'0')*sign;
			}
			else if(inf.flag)
			{	factor/=10;	//decrement the place value
						//of last digit
				inf.el.fval+=(in[i]-'0')*factor*sign;
			}
			else
			  inf.el.ival=10*inf.el.ival+(int)(in[i]-'0')*sign;

			if(symb(in[i+1])||in[i+1]==';')
			  expr.push(inf);
		}
		else if(in[i]=='.')
		{	inf.el.fval=(float)inf.el.ival;
			inf.flag=1;	//INPUT is float type

			factor=1;	//Reset the place value
					//of last digit added
			if(symb(in[i+1])||in[i+1]==';')
			  expr.push(inf);
		}
	}
	if(ctr>0)
	  while(ctr)
	  {	info inf={')',2};
		expr.push(inf);
		ctr--;
	  }

	else if(ctr<0)
	{	cout<<"Error!!! More right paranthesis!!!";
		return -1;
	}
	temp.write(in,(i-1));
	temp<<'\n';
	exp_flag=1;
	return 0;
}

char symb(char c)
{	switch(c)
	{ case '^':return 9;
	  case '/':return 8;
	  case '*':return 8;
	  case '+':return 7;
	  case '-':return 7;
	  case '(':return -1;
	  case ')':return 1;
	  default :return 0;
	}

}

void display(Queue exp)
{	info inf={0,0};
	while(inf.flag!=-5)
	{	inf=exp.pop();
		switch(inf.flag)
		{ case 0 :cout<<"\nInteger : "<<inf.el.ival;break;
		  case 1 :cout<<"\nFloat   : "<<inf.el.fval;break;
		  case 2 :cout<<"\nOperator: "<<inf.el.sym;break;
		  case -5:cout<<"\nEnd ofExpression";break;
		  default:cout<<"\nError in output";
		}
	}
}

void post_convert()
{	Queue temp;
	Stack symbols;
	info psym,pexp={'(',2};
	symbols.push(pexp);

	while(pexp.flag!=-5)
	{	pexp=expr.pop();
		if(pexp.flag==2)
		{	psym=symbols.peek();
			while((symb(psym.el.sym)>symb(pexp.el.sym))
							&&pexp.el.sym!='(')
			{	psym=symbols.pop();	//Push all operators of
				temp.push(psym);	//greater precedence
				psym=symbols.peek();	//into expr
			}
			if(pexp.el.sym==')')	//If the symbol is ')' , then
			  symbols.pop();	//remove '(' from the symbols
			else                    //Else push the symbol into
			  symbols.push(pexp);	//the symbols stack
		}
		else if(pexp.flag==-5)
		{	psym=symbols.pop();
			while(psym.el.sym!='(')
			{	temp.push(psym);
				psym=symbols.pop();
			}
		}
		else
		  temp.push(pexp);
	}
	expr=temp;

}

int evaluate()
{	Stack eval;
	info pexp,pnum,op1,op2,res;
	int ctr=0;
	pexp=expr.pop();
	do
	{       ctr++;
		if(pexp.flag==1||pexp.flag==0)  //if element is a number
		  eval.push(pexp);		//push into stack
		else if(pexp.flag==2)
		{ op2=eval.pop();
		  op1=eval.pop();
		  if(op1.flag||op2.flag)	//if op1 or op2 is float type
		    res.flag=1;			//the result is float
		  else if(op1.flag==-5)         //else if there is no element
		    cout<<"Too less operands";	//in stack, display error
		  else				//else
		    res.flag=0;			//the result is int type

		  switch(pexp.el.sym)
		  { case '+' :if(res.flag)
				res.el.fval=
				  (op1.flag?op1.el.fval:op1.el.ival)+
				      (op2.flag?op2.el.fval:op2.el.ival);
			      else
				res.el.ival=
				  (op1.flag?op1.el.fval:op1.el.ival)+
				      (op2.flag?op2.el.fval:op2.el.ival);
			      break;
		    case '-' :if(res.flag)
				res.el.fval=
				  (op1.flag?op1.el.fval:op1.el.ival)-
				      (op2.flag?op2.el.fval:op2.el.ival);
			      else
				res.el.ival=
				  (op1.flag?op1.el.fval:op1.el.ival)-
				      (op2.flag?op2.el.fval:op2.el.ival);
			      break;
		    case '*' :if(res.flag)
				res.el.fval=
				  (op1.flag?op1.el.fval:op1.el.ival)*
				      (op2.flag?op2.el.fval:op2.el.ival);
			      else
				res.el.ival=
				  (op1.flag?op1.el.fval:op1.el.ival)*
				      (op2.flag?op2.el.fval:op2.el.ival);
			      break;
		    case '/' :if(res.flag)
				res.el.fval=
				  (op1.flag?op1.el.fval:op1.el.ival)/
				      (op2.flag?op2.el.fval:op2.el.ival);
			      else
				res.el.ival=
				  (op1.flag?op1.el.fval:op1.el.ival)/
				      (op2.flag?op2.el.fval:op2.el.ival);
			      break;
		    default  :cout<<"\nError!!in eval"<<pexp.el.sym;return-1;
		  }
		  eval.push(res);
		}
		pexp=expr.pop();


	}while(pexp.flag!=-5);



	res=eval.pop();
	op1=eval.pop();

	if(op1.flag!=-5)
	  return -1;


	cout<<"OUTPUT of expressions in the last line : "
	    <<(res.flag?res.el.fval:res.el.ival)<<'\n';
	temp<<'$'<<'#';
	temp.write((char*) &res,sizeof res);

	return 0;


}

/*******************************End of Definitions****************************/


/***********************Definition of Queue class functions*******************/
void Queue::push(info n)
{       if(front==NULL)
	  front=rear=new node;
	else
	{	rear->next=new node;
		rear=rear->next;
	}

	if(rear==NULL)
	cout<<"Error cannot insert in Q";

	rear->inf=n;
}


info Queue::pop()
{	if(front==NULL)
	{	info temp={0,-5};
		return temp;
	}

	info temp=front->inf;
	node *temptr=front;
	if(front==rear) front=rear=NULL;
	else
	  front=front->next;
	delete temptr;

	return temp;
}


/*******************************End of Definitions****************************/


/*********************Function Definitions of Stack Class**********************/


void Stack::push(info n)
{	node* temp=new node;
	if(temp==NULL)
	{	cout<<"Cannot insert into stack!!!";
		return;
	}
	temp->inf=n;
	temp->next=top;
	top=temp;
}


info Stack::pop()
{	if(top==NULL)
	{	info temp={0,-5};
		return temp;
	}

	info n=top->inf;
	node* temp=top;
	top=top->next;
	delete 	temp;
	return n;
}



/********************************End of Definitions***************************/

>>This, was working till i changed the input style. From gets to cin.get
gets() was wrong to begin with. and cin.get() does not do the same thing as gets(). What you probably wanted was cin.getline() or std::getline().

BTY I fixed up the code tags in your post. [icode] is intended for only one line of code so that it can appear on the same line as the describing text.

but getline reads whole line. i cannot ignore spaces with it.
with cin.get i can ignore spaces...

sorry! i forgot to mention!
i've added some cout statements in between the "file.cpp" file to site the error!
i found that that in line 345 in function evaluate(), the if statement is being executed.
it might mean there's some error in

  1. inserting into queue,
  2. converting into postfix (inserting into stack)
  3. postfix evaluation
  4. or, more likely, handling exceptions in inserting![insert() function]

I couldnot pin point the error till now!

Also, in "file.cpp"
to stop enterin into file, u got to press ctrl+g.

gets() ignores spaces too :)

Use the >> operator to ignore spaces cin >> word;

but when i use >> operator i cannot read wat comes after a blank space!
i want to read everythin in an expression, ignoring the white spaces!
like
== 12-8;
and ==12 -
8 ;
should evaluate to same result.

weird, division works!!!
==34/2;
gives the output 17
but nothing else does!

Your problem seems to be trying to get your input commands to do the processing for you. That's difficult at best. Just read in the entire line as suggested and look at the line character by character. That is basically all cin.get() does anyway.

Sorry! The prblem was not with the change in input.
I messed up with the way -ve numbers r handled and the way infix is converted to postfix.
in file.cpp
line 250:'>' should be replaced by '>='
line169:the statement MinusFlag=0; need to be added.

anyway! Thanx for trying to help me!!!

Especially Ancient Dragon and Walt P!!!

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.