# Stack Based Calculator- Due in 8 hours

Hello Everyone,
I usually don't use sites like this but I really need help with a program I must write using c++. I have tried to write this program but  it is a complete mess so I am not going to bother posting it. Anyway, this is what I must Do :

Design and build a parsing calculator.  Your program must

accept a string of the form  12 * 3 / (123 + 4) ,
do the specified calculation,  and
display the result.

The program    should continue to ask for input until the user decides to quit.

In addition,  this program must use a stack to implement the calculation.  YouÃƒÂ¢Ã‚Â€Ã‚Â™ll have to

accept the input as a character string,
break it up into its component parts,  and
convert it to numbers and operators, and
do the calculation.Notes:
1.  Instead of the usual precedence, evaluate expressions from left
to right, but make sure that operations done inside parentheses
are done first.  For example, the expression  22 *  3 + ( 2 * 3) ,
should be evaluated:          22 * 3 +  ( 6)      66 + 6
Look up and use the following standard library functions to help with your design:
char* strtok(char*, char*)              double atof(char*)

Kumar
###### Who is Participating?

Commented:
you have to define the priority of the operators, and u can refer to the code below.

regards,
charles
``````#include <iostream>
#include <stdio.h>
#include <math.h>
#include <stdlib.h>
using namespace std;
#define DEAFAULT_SIZE 20
template <class Type>
class CCStack
{
private:
Type* base;
Type* top;
int size;
public:
CCStack(int size = DEAFAULT_SIZE);
~CCStack();
bool isFull() const;   //Judge the Stack is full or not.
bool isEmpty() const;   //Judge the Stack is empty or not.
bool getTop(Type &item) const;  //get the top element
bool push(const Type &item); //add item to stack
bool pop(Type &item);        //pop top into item
};

template <class Type>
CCStack<Type>::CCStack(int size)
{
if(!(base=new Type[size*sizeof(Type)]))
{
cout << "Error!Failure to apply the memory space." << endl;
exit(-1);
}
top = base;
}

template <class Type>
CCStack<Type>::~CCStack()
{
delete[] base;
base = NULL;
}

template <class Type>
bool CCStack<Type>::getTop(Type &item) const
{

if(top > base)
{
item = *(top-sizeof(Type));
}
else
{
return false;
}
return true;
}

template <class Type>
bool CCStack<Type>::push(const Type &item)
{
if(!isFull())
{
*top = item;
top = top+sizeof(Type);
}
return true;
}

template <class Type>
bool CCStack<Type>::pop(Type &item)
{
if(!isEmpty())
{
top = top-sizeof(Type);
item = *top;
}
return true;
}

template <class Type>
bool CCStack<Type>::isFull() const
{
if(top >= base + size*sizeof(Type))
{
return true;
}
else
{
return false;
}
}

template <class Type>
bool CCStack<Type>::isEmpty() const
{
if( top == base )
{
return true;
}
else
{
return false;
}
}

template <class Type>
class CCOperator
{
private:
public:
CCOperator();
~CCOperator();
char compareOpt(char temp_first,char temp_second);
Type standardOpt(Type temp_prefix,char temp_opt,Type temp_postfix);
bool isOpt(char c);
};
template <class Type>
CCOperator<Type>::CCOperator()
{

}

template <class Type>
CCOperator<Type>::~CCOperator()
{

}
template <class Type>
char CCOperator<Type>::compareOpt(char temp_first,char temp_second)
{
char pri;
switch(temp_second)
{
case '+':
case '-':
if(temp_first=='('||temp_first=='=')
{
pri='<';
}
else
{
pri='>';
}
break;
case '*':
case '/':
if(temp_first=='*'||temp_first=='/'||temp_first==')')
{
pri='>';
}
else
{
pri='<';
}
break;
case '(':
if(temp_first==')')
{
printf("\n\t Expression form error\n");
exit(-1);
}
else
{
pri='<';
}
break;
case ')':
switch(temp_first)
{
case'(':
pri='=';
break;
case'=':
printf("\n\t Expression form error\n");
exit(-1);
default :
pri='>';
}
break;
case'=':
switch(temp_first)
{
case'=':
pri='=';
break;
case'(' :
printf("\n\t Expression form error\n");
exit(-1);
default :
pri='>';
}
break;

default:
{
printf("\n\t Unknown operator \n");
pri = 0;
}
break;
}
return pri;
}

template <class Type>
Type CCOperator<Type>::standardOpt(Type temp_prefix,char temp_opt,Type temp_postfix)
/* Pre: Already have two Nums and one Opt .
Post:Return the result of calculate. */
{
Type temp_result;
switch(temp_opt)
{
case'+':temp_result=temp_prefix+temp_postfix;break;
case'-':temp_result=temp_prefix-temp_postfix;break;
case'*':temp_result=temp_prefix*temp_postfix;break;
case'/':
if(temp_postfix != 0)
{
temp_result=temp_prefix/temp_postfix;

}
else
{
printf("\n\t Calculate error \n");
}
break;
default:
{
printf("\n\t Unsupport operator \n");
break;
}
}
return temp_result;
}

template <class Type>
bool CCOperator<Type>::isOpt(char c)
{
switch(c)
{
case '+':
case '-':
case '*':
case '/':
case '(':
case ')':
case '=':
return true;
default:
return false;
}
}

bool doCalculate()
{
CCStack<double> stackSZ;
CCStack<char> stackZF;
CCOperator<double> calculatorOpt;

char temp_opt;                      //Temporary Operation Saver.
double temp_number;                 //Temporary Number Saver.
double temp_prefix,temp_postfix;    //Temporary Opt Prefix(Number),Postfix(Number) Saver.
double temp_final;                  //Temporary Midway Final Saver.
double final;                       //The Final Calculate Result.
char temp_c;                        //Temporary Get One Char.
char convert_str2double[100];       //Use For Convert String To Double.
int judge=0;                        //The Currently Digit Saver.

stackZF.push('=');
temp_c=getchar();  //Get The First Char.

judge++;
stackZF.getTop(temp_opt);   // Get the Top Element Of the StackZF.
while(temp_c != '=' || temp_opt != '=')
{
if(calculatorOpt.isOpt(temp_c)) // Judge "temp_c" is Opt or not.
{
switch(calculatorOpt.compareOpt(temp_opt,temp_c)) // Return The PRI State: ">" , "<" or "=".
{
case '<': //Top Element PRI < temp_c.
stackZF.push(temp_c);
temp_c=getchar();
stackZF.getTop(temp_opt);
break;
case '='://Shuck Off The "( )" And Calculate "temp_final".
stackZF.pop(temp_opt);
stackZF.getTop(temp_opt);
temp_c=getchar();
break;

case '>'://Pop From the stackZF And stackSZ and Do Calculate.
if(temp_opt=='+'||temp_opt=='-'||temp_opt=='*'||temp_opt=='/')
{
stackZF.pop(temp_opt);
stackSZ.pop(temp_postfix);
stackSZ.pop(temp_prefix);
temp_final=calculatorOpt.standardOpt(temp_prefix,temp_opt,temp_postfix); //Calculate Out The temp_final.
stackSZ.push(temp_final);
stackZF.getTop(temp_opt);
break;
}
else
{
break;
}
}
}
else if((temp_c>='0' && temp_c<='9') || temp_c=='.') //Combination The Number(Double)
{
int i=0;
do
{
convert_str2double[i]=temp_c;
i++;
temp_c=getchar();
}while((temp_c<='9' && temp_c>='0') || temp_c=='.');
convert_str2double[i]=0;
temp_number=atof(convert_str2double); //Use The Function atof() to Convert A String Var To A Double One.
stackSZ.push(temp_number);
}
else
{
//ERROR
}
}
stackSZ.getTop(final);

printf("\nResultï¼š%15.15f",final);

return 0;
}
int main()
{
doCalculate();
return 0;
}
``````
0

Software ArchitectCommented:
Looks like you haven't started to do your homework. If so, would be almost impossible to terminate it in 8 hours, you have to learn lot of concepts. Even worst in these hours.
0

Author Commented:
Here is my code . Its a mess and I think Im better off rewriting it. Everything works except for evaluating parenthesis :

#include <iostream>
#include <stdio.h>

#include <string.h>
#include <stddef.h>
#include <Stdlib.h>

using namespace std;
#define DEAFAULT_SIZE 20
class Stack
{
private:
int size;
int top;
char* values;
public:
Stack(int size = DEAFAULT_SIZE);
virtual ~Stack();
bool isFull();
bool isEmpty();
void push(char input);
char pop();
};
Stack::Stack(int size)
{
this->size = size;
values = new char[size];
top = -1;
}
Stack::~Stack()
{
delete[] values;
}
bool Stack::isFull()
{
if(top < size-1)
{
return false;
}
else
{
return true;
}
}
bool Stack::isEmpty()
{
if(top == -1)
{
return true;
}
else
{
return false;
}
}
void Stack::push(char input)
{
if(!isFull())
{
top++;
values[top] = input;
}
}
char Stack::pop()
{
char retVal;
if(!isEmpty())
{
retVal = values[top];
top--;
}
return retVal;
}
class Stackdouble
{
private:
int size;
int top;
double* values;
public:
Stackdouble(int size = DEAFAULT_SIZE);
virtual ~Stackdouble();
bool isFull();
bool isEmpty();
void push(double input);
double pop();
};
Stackdouble::Stackdouble(int size)
{
this->size = size;
values = new double[size];
top = -1;
}
Stackdouble::~Stackdouble()
{
delete[] values;
}
bool Stackdouble::isFull()
{
if(top < size-1)
{
return false;
}
else
{
return true;
}
}
bool Stackdouble::isEmpty()
{
if(top == -1)
{
return true;
}
else
{
return false;
}
}
void Stackdouble::push(double input)
{
if(!isFull())
{
top++;
values[top] = input;
}
}
double Stackdouble::pop()
{
double retVal;
if(!isEmpty())
{
retVal = values[top];
top--;
}
return retVal;
}
class Evaluate
{
public:
Stack operators;
Stackdouble operands;
Stack operators2;
Stackdouble operands2;
Evaluate();
double EvaluateEx();
double EvaluateParenthesis(Stack &one, Stackdouble &two,double &value);
void getInput();
};
Evaluate::Evaluate()
{
}

double Evaluate::EvaluateEx()
{
double value = 0.0;
double one;
double two;
char array[] = "  ( 8 + 0 ) + ( 7 + 0 ) ";

char delims[] = " ";
char *token = NULL;
token = strtok( array, delims );

operators.push(*token);
do
{
printf("token: %s\n", token);
switch(*token)
{
case '+':
this->operators.push(*token);
continue;
case '-':
this->operators.push(*token);
continue;
case '*':
this->operators.push(*token);
continue;
case '/':
this->operators.push(*token);
continue;
case ')':
this->operators.push(*token);
continue;

case '(':
//cout << "nigga ";
this->operators.push(*token);
continue;

default:
double convert =  atof(token);

this->operands.push(convert);
continue;
}
}
while (token = strtok(NULL, " "));
do
{
char ope;

one = operands.pop();
//cout << one << "\n";
ope = operators.pop();
//cout << ope << "\n";
two = operands.pop();
//cout << two;
if(ope == ')')
{
ope = operators.pop();
one = operands.pop();
two = operands.pop();
if(ope == '+')
{

value = one + two;
this->operands.push(value);
//cout << "\n" << value;

}
if(ope == '-')
{
value = two - one;
this->operands.push(value);
cout << "\n \n" << value;

}
if(ope == '*')
{
value = two * one;
this->operands.push(value);

}
if(ope == '/')
{
value = two / one;
this->operands.push(value);
}
ope = operators.pop();
if( ope == '(')
break;
}

if(ope == '+')
{

value = one + two;
this->operands.push(value);
// cout << "\n" << value;
continue;
}
if(ope == '-')
{
value = two - one;
this->operands.push(value);
continue;
}
if(ope == '*')
{
value = two * one;
this->operands.push(value);
continue;
}
if(ope == '/')
{
value = two / one;
this->operands.push(value);
continue;
}

}

while(!this->operators.isEmpty());

return value;
}

int main()
{
Evaluate k;
double r = k.EvaluateEx();
cout << "\n \n \n" << r;

}

0

Commented:
--> eliminate the paranthesis using stack
12*3/(1+(1+1))
-> push current expression on stack.
-> parse for the first paranthesis expression. and push it on stack. at this stage you wud have stack as
12*3/X
then
1+(1+1)
-> repeat step 2.
Now stack would be as
12*3/X
then
1+X
then
1+1

-> repeat stack you until you dont find any expression with paranthesis.

now resolve the stack.

12*3/X
then
1+X
then
1+1

becomes

12*3/X
then
1+X
then
2

which becomes

12*3/X
then
1+2

which becomes

12*3/X
then
3

which becomes

12*3/3

which you can solve. :)

Here i have taken 'X' as a token to identify the place to put the value of the expression of the popped stack expression.

Hope it helps.
0

Author Commented:
Thanks for the help but I get the concept but Im having trouble implementing it into my code. I seem to get zero values whenever I try to evaluate parenthesis.
0

Commented:
>>void Stack::push(char input)
according to the logic i described, you should have passed the whie expression on to the stack.

make it:
void Stack::push(char* input)

-> why are you using class Stackdouble. seems like its of no use.

-> nowhere i cud find the logic of finding the paranthesized expression.
if you find '(' then find CORRESPONDING ')'

you are pushing tokens on to the stack even when its '('. you should have pushed it only when you find CORRESPONDING ')' (not push on stack even if it is ')' but not the corresponding one)

Kumar, please revamp your code fixing above said flaws and revert back. We can discuss further.

Hope it Helps.

regards,
James

0

Author Commented:
but see I have to use the strtok() and atof() methods in order to get credit for this assignment so it seems as if i should split the input into tokens and then add it to the stack. I was wondering if I should use one stack or two stack ?
0

Commented:
atof() -> u can always use it while calculating the popped up stack expression
strtok() -> u can use it as :

case '(' :
1. set a flag to true;
2. parse further and record the string in between:
if you get the next token as ')', take the string as expression. replace it with 'X' in the pushed up expression and push the string on to the stack.
if you get next token as '(' then repeat step 2.
0

Commented:
one stack is okay.
while popping up do a check for paranthesis.
if paranthesis is still their. again repeat the above said 2 steps.
0

Author Commented:
Im still having the same problem. Heres my simplified code :

double Evaluate::EvaluateEx()
{
double value = 0.0;

char array[] = "   ( 7 + 9 ) + ( 6 + 3 )  ";

char delims[] = " ";
char *token = NULL;
token = strtok( array, delims );

stack.push(*token);
do
{
printf("token: %s\n", token);
this->stack.push(*token);
continue;
}
while (token = strtok(NULL, " "));
char one,two,three;

while(!stack.isEmpty())
{
one = stack.pop();
two = stack.pop();
three = stack.pop();

if(two == '+')
{

value +=  atof(&one) + atof(&three);
continue;
}
if(two == ')')
{
if(two == '(')
break;
continue;
}
}

Sorry If Im hasseling you man but Im really confused

return value;
}

int main()
{
Evaluate k;
double r = k.EvaluateEx();
cout << "\n \n \n" << r;

}
0

Commented:
>>char one,two,three;
why are you pushing and popping only chars on to the stack. I mean we have to push the expressions on the it. right?

please use char* instead of it. then we will take it forward.

0

Author Commented:
alrite i Have changed everythingto char* pointers but now my program freezes. Please check my code and see what I Did wrong :

#include <iostream>
#include <stdio.h>

#include <string.h>
#include <stddef.h>
#include <Stdlib.h>

using namespace std;
#define DEAFAULT_SIZE 20
class Stack
{
private:
int size;
int top;
char* values;
public:
Stack(int size = DEAFAULT_SIZE);
virtual ~Stack();
bool isFull();
bool isEmpty();
void push(char *input);
char* pop();
};
Stack::Stack(int size)
{
this->size = size;
values = new char[size];
top = -1;
}
Stack::~Stack()
{
delete[] values;
}
bool Stack::isFull()
{
if(top < size-1)
{
return false;
}
else
{
return true;
}
}
bool Stack::isEmpty()
{
if(top == -1)
{
return true;
}
else
{
return false;
}
}
void Stack::push(char *input)
{
if(!isFull())
{
top++;
values[top] = *input;
}
}
char* Stack::pop()
{
char *retVal;
if(!isEmpty())
{
*retVal = values[top];
top--;
}
return retVal;
}

class Evaluate
{
public:
Stack stack;

Evaluate();
double EvaluateEx();

};
Evaluate::Evaluate()
{
}

double Evaluate::EvaluateEx()
{
double value = 0.0;

char array[] = " ( 6 + 3 ) ";

char delims[] = " ";
char *token = NULL;
token = strtok( array, delims );

stack.push(token);
do
{
printf("token: %s\n", token);
this->stack.push(token);
continue;
}
while (token = strtok(NULL, " "));
char *one,*two,*three;
//   double value;
while(!stack.isEmpty())
{
one = stack.pop();
two = stack.pop();
three = stack.pop();

if(*two == '+')
{

value +=  atof(one) + atof(three);
continue;
}
if(*two == ')')
{
cout << "hello";
two = stack.pop();
if(*two == '(')
break;
if(*two == '+')
{
value +=  atof(one) + atof(three);
break;
}
continue;
}
}

return value;
}

int main()
{
Evaluate k;
double r = k.EvaluateEx();
cout << "\n \n \n" << r;

}

0

Commented:
>>values[top] = *input;
>>*retVal = values[top];

use functions like strcpy.
0

Commented:
>>char* values;
ur stack is able to hold only one expression.
make it an array or a vector.

0

Commented:
Kumar, please rectify the code in the lines of above two posts and revert back.
0

Commented:
you can define a stack template.
You'd better to use 2 stacks, one is used to pocess data, the other is used to process operators.
I will show you a sample below.
``````#define DEAFAULT_SIZE 20
template <class Type>
class CCStack
{
private:
Type* base;
Type* top;
int size;
public:
CCStack(int size = DEAFAULT_SIZE);
~CCStack();
bool isFull() const;   //Judge the Stack is full or not.
bool isEmpty() const;   //Judge the Stack is empty or not.
bool clearStack();      //(Temporary Scheme) to reset the Stack.
bool getTop(Type &item) const;  //get the top element
bool push(const Type &item); //add item to stack
bool pop(Type &item);        //pop top into item
};

template <class Type>
CCStack<Type>::CCStack(int size)
{
if(!(base=new Type[size*sizeof(Type)]))
{
cout << "Error!Failure to apply the memory space." << endl;
exit(-1);
}
top = base;
}

template <class Type>
CCStack<Type>::~CCStack()
{
delete[] base;
base = NULL;
}

template <class Type>
bool CCStack<Type>::push(const Type &item)
{
if(!isFull())
{
*top = item;
top = top+sizeof(Type);
}
return true;
}

template <class Type>
bool CCStack<Type>::pop(Type &item)
{
if(!isEmpty())
{
item = *top;
top = top-sizeof(Type);
}
return true;
}

template <class Type>
bool CCStack<Type>::isFull()
{
if(top >= base + size*sizeof(Type))
{
return true;
}
else
{
return false;
}
}

template <class Type>
bool CCStack<Type>::isEmpty()
{
if( top == base )
{
return true;
}
else
{
return false;
}
}
``````
0

Commented:
yuy,
its against the EE ethics to help somebody in his/her assignment with code directly. It would be nice if you give him some comments so that he can rectify and LEARN.

Best Regards,
James
0

Commented:
Kumar, as a new comer to this site, hope you wont mind my above comment. But its a sort of rule.....

proceeeding with ur posted code:
in ur class STack:
>>   char* values;
try making it a vector of char*. My suggestion is to work with vector of CString.
all you need to do as additional change in class stack is to convert CString to char* and vice versa.

For that:
char* to CString  -> CString(char*) can work.

CString to char* -> use wcstombs_s method.check out :
http://forums.microsoft.com/MSDN/ShowPost.aspx?PostID=180377&SiteID=1

in ur evaluateEx method:

>>   token = strtok( array, delims );
>>   stack.push(token);
>>   do
>>   {
>>      printf("token: %s\n", token);
>>      this->stack.push(token);
>>      continue;
>>   }

dont use the variable names as 'array', it a keyword in c++.
u r parsing it in tokens.
here only you can do :
1. identify the innermost paranthesis expression. Let term it as EXP. If no expression, then parse the whole string from left to right and calculate the value.
2. push this whole string (i.e. char*) after replacing the EXP with token 'X'
3. pop the stack, evaluate the expression and store the value. again pop the stack, Replace 'X' with the stored value. Then GOTO 1.

So,you need to change your eaveluateEx method code and the funda of stack class (becoz it is storing only chars not the strings and you need a stack of strings).

Let me know where you are stuck now. Hope it helps.

0

Commented:
Kumar,

you opened a new thread in http:Q_22981924.html but the maximum points for one question is 500 points. You should go to http://www.experts-exchange.com/Community_Support/General/ and ask a 0 points question to delete the second thread (as it has two answers only).

Regards, Alex
0

Author Commented:
charles,

If you could explain your code a little more that would be great. I have no exsprience with templates .
0

Author Commented:
I have changed my code to this :

#include <iostream>
#include <stdio.h>
#include <string>

#include <math.h>
#include "stdafx.h"
#include <stdlib.h>

#define DEAFAULT_SIZE 20
//using namespace std;
template <class evaluate>

class CCStack
{
private:
char* base;
char* top;
int size;
public:
CCStack(int size = DEAFAULT_SIZE);
~CCStack();
bool isFull() const;   //Judge the Stack is full or not.
bool isEmpty() const;   //Judge the Stack is empty or not.
bool getTop(char &item) const;  //get the top element
bool push(const char &item); //add item to stack
bool pop(char &item);        //pop top into item
};

template <class evaluate>
CCStack<evaluate>::CCStack(int size)
{
if(!(base=new char[size*sizeof(char)]))
{
cout << "Error!Failure to apply the memory space." << endl;
exit(-1);
}
top = base;
}

template <class evaluate>
CCStack<evaluate>::~CCStack()
{
delete[] base;
base = NULL;
}

template <class evaluate >
bool CCStack<evaluate>::getTop(char &item) const
{

if(top > base)
{
item = *(top-sizeof(char));
}
else
{
return false;
}
return true;
}

template <class evaluate>
bool CCStack<evaluate>::push(const char &item)
{
if(!isFull())
{
*top = item;
top = top+sizeof(item);
}
return true;
}

template <class evaluate>
bool CCStack<evaluate>::pop(char &item)
{
if(!isEmpty())
{
top = top-sizeof(char);
item = *top;
}
return true;
}

template <class evaluate>
bool CCStack<evaluate>::isFull() const
{
if(top >= base + size*sizeof(char))
{
return true;
}
else
{
return false;
}
}

template <class evaluate>
bool CCStack<evaluate>::isEmpty() const
{
if( top == base )
{
return true;
}
else
{
return false;
}
}

template <class evaluate>
class CCOperator
{
private:
public:
CCOperator();
~CCOperator();
char compareOpt(char temp_first,char temp_second);
double standardOpt(double temp_prefix,char temp_opt,double temp_postfix);
bool isOpt(char c);
};
template <class evaluate>
CCOperator<evaluate>::CCOperator()
{

}

template <class evaluate>
CCOperator<evaluate>::~CCOperator()
{

}
template <class evaluate>
char CCOperator<evaluate>::compareOpt(char temp_first,char temp_second)
{
char pri;
switch(temp_second)
{
case '+':
case '-':
if(temp_first=='('||temp_first=='=')
{
pri='<';
}
else
{
pri='>';
}
break;
case '*':
case '/':
if(temp_first=='*'||temp_first=='/'||temp_first==')')
{
pri='>';
}
else
{
pri='<';
}
break;
case '(':
if(temp_first==')')
{
printf("\n\t Expression form error\n");
exit(-1);
}
else
{
pri='<';
}
break;
case ')':
switch(temp_first)
{
case'(':
pri='=';
break;
case'=':
printf("\n\t Expression form error\n");
exit(-1);
default :
pri='>';
}
break;
case'=':
switch(temp_first)
{
case'=':
pri='=';
break;
case'(' :
printf("\n\t Expression form error\n");
exit(-1);
default :
pri='>';
}
break;

default:
{
printf("\n\t Unknown operator \n");
pri = 0;
}
break;
}
return pri;
}

template <class evaluate>
double CCOperator<evaluate>::standardOpt(double temp_prefix,char temp_opt,double temp_postfix)
/* Pre: Already have two Nums and one Opt .
Post:Return the result of calculate. */
{
double temp_result;
switch(temp_opt)
{
case'+':temp_result=temp_prefix+temp_postfix;break;
case'-':temp_result=temp_prefix-temp_postfix;break;
case'*':temp_result=temp_prefix*temp_postfix;break;
case'/':
if(temp_postfix != 0)
{
temp_result=temp_prefix/temp_postfix;

}
else
{
printf("\n\t Calculate error \n");
}
break;
default:
{
printf("\n\t Unsupport operator \n");
break;
}
}
return temp_result;
}

template <class evaluate>
bool CCOperator<evaluate>::isOpt(char c)
{
switch(c)
{
case '+':
case '-':
case '*':
case '/':
case '(':
case ')':
case '=':
return true;
default:
return false;
}
}

bool doCalculate()
{
CCStack<double> stackSZ;
CCStack<char> stackZF;
CCOperator<double> calculatorOpt;

char temp_opt;                      //Temporary Operation Saver.
double temp_number;                 //Temporary Number Saver.
double temp_prefix,temp_postfix;    //Temporary Opt Prefix(Number),Postfix(Number) Saver.
double temp_final;                  //Temporary Midway Final Saver.
double final;                       //The Final Calculate Result.
char temp_c;                        //Temporary Get One Char.
char convert_str2double[100];       //Use For Convert String To Double.
int judge=0;                        //The Currently Digit Saver.

stackZF.push('=');
temp_c=getchar();  //Get The First Char.

judge++;
stackZF.getTop(temp_opt);   // Get the Top Element Of the StackZF.
while(temp_c != '=' || temp_opt != '=')
{
if(calculatorOpt.isOpt(temp_c)) // Judge "temp_c" is Opt or not.
{
switch(calculatorOpt.compareOpt(temp_opt,temp_c)) // Return The PRI State: ">" , "<" or "=".
{
case '<': //Top Element PRI < temp_c.
stackZF.push(temp_c);
temp_c= getchar();
stackZF.getTop(temp_opt);
break;
case '='://Shuck Off The "( )" And Calculate "temp_final".
stackZF.pop(temp_opt);
stackZF.getTop(temp_opt);
temp_c= getchar();
break;

case '>'://Pop From the stackZF And stackSZ and Do Calculate.
if(temp_opt=='+'||temp_opt=='-'||temp_opt=='*'||temp_opt=='/')
{
stackZF.pop(temp_opt);
stackSZ.pop(temp_postfix);
stackSZ.pop(temp_prefix);
temp_final=calculatorOpt.standardOpt(temp_prefix,temp_opt,temp_postfix); //Calculate Out The temp_final.
stackSZ.push(temp_final);
stackZF.getTop(temp_opt);
break;
}
else
{
break;
}
}
}
else if((temp_c>='0' && temp_c<='9') || temp_c=='.') //Combination The Number(Double)
{
int i=0;
do
{
convert_str2double[i]=temp_c;
i++;
temp_c= 'c';
}while((temp_c<='9' && temp_c>='0') || temp_c=='.');
convert_str2double[i]=0;
temp_number=atof(convert_str2double); //Use The Function atof() to Convert A String Var To A Double One.
stackSZ.push(temp_number);
}
else
{
//ERROR
}
}
stackSZ.getTop(final);

printf("\nResultÃ¯Â¼Âš%15.15f",final);

return 0;
}
int main()
{
doCalculate();
return 0;
}

I get the following errors:

Error      5      error C2664: 'CCStack<evaluate>::pop' : cannot convert parameter 1 from 'double' to 'char &'      c:\Documents and Settings\Administrator\My Documents\Visual Studio 2005\Projects\test\test\test.cpp      299
Error      6      error C2664: 'CCStack<evaluate>::pop' : cannot convert parameter 1 from 'double' to 'char &'      c:\Documents and Settings\Administrator\My Documents\Visual Studio 2005\Projects\test\test\test.cpp      300
Error      9      error C2664: 'CCStack<evaluate>::getTop' : cannot convert parameter 1 from 'double' to 'char &'      c:\Documents and Settings\Administrator\My Documents\Visual Studio 2005\Projects\test\test\test.cpp      330

0

Commented:
The errors are pretty self-explanatory :

>> cannot convert parameter 1 from 'double' to 'char &'

It means you're trying to pass a double where a char& is expected.

It means that the compiler doesn't know the identifier ... Check whether the identifier is defined (do you have the proper include ?).
0

Author Commented:
alrite i get no compilier errors but when i run it , it does nothing. It asks for a expression to calculate, and nothing happens after that:

#include <iostream>
#include <stdio.h>
#include <math.h>
#include <stdlib.h>
using namespace std;
#define DEAFAULT_SIZE 20
template <class t>
class CCStack
{
private:
char* base;
char* top;
int size;
public:
CCStack(int size = DEAFAULT_SIZE);
~CCStack();
bool isFull() const;   //Judge the Stack is full or not.
bool isEmpty() const;   //Judge the Stack is empty or not.
bool getTop(char &item) const;  //get the top element
bool push(const char &item); //add item to stack
bool pop(char &item);        //pop top into item
};

template <class t>
CCStack<t>::CCStack(int size)
{
if(!(base=new char[size*sizeof(char)]))
{
cout << "Error!Failure to apply the memory space." << endl;
exit(-1);
}
top = base;
}

template <class t>
CCStack<t>::~CCStack()
{
delete[] base;
base = NULL;
}

template <class t>
bool CCStack<t>::getTop(char &item) const
{

if(top > base)
{
item = *(top-sizeof(char));
}
else
{
return false;
}
return true;
}

template <class t>
bool CCStack<t>::push(const char &item)
{
if(!isFull())
{
*top = item;
top = top+sizeof(char);
}
return true;
}

template <class t>
bool CCStack<t>::pop(char &item)
{
if(!isEmpty())
{
top = top-sizeof(char);
item = *top;
}
return true;
}

template <class t>
bool CCStack<t>::isFull() const
{
if(top >= base + size*sizeof(char))
{
return true;
}
else
{
return false;
}
}

template <class t>
bool CCStack<t>::isEmpty() const
{
if( top == base )
{
return true;
}
else
{
return false;
}
}

template <class t>
class CCOperator
{
private:
public:
CCOperator();
~CCOperator();
char compareOpt(char temp_first,char temp_second);
double standardOpt(double temp_prefix,char temp_opt,double temp_postfix);
bool isOpt(char c);
};
template <class t>
CCOperator<t>::CCOperator()
{

}

template <class t>
CCOperator<t>::~CCOperator()
{

}
template <class t>
char CCOperator<t>::compareOpt(char temp_first,char temp_second)
{
char pri;
switch(temp_second)
{
case '+':
case '-':
if(temp_first=='('||temp_first=='=')
{
pri='<';
}
else
{
pri='>';
}
break;
case '*':
case '/':
if(temp_first=='*'||temp_first=='/'||temp_first==')')
{
pri='>';
}
else
{
pri='<';
}
break;
case '(':
if(temp_first==')')
{
printf("\n\t Expression form error\n");
exit(-1);
}
else
{
pri='<';
}
break;
case ')':
switch(temp_first)
{
case'(':
pri='=';
break;
case'=':
printf("\n\t Expression form error\n");
exit(-1);
default :
pri='>';
}
break;
case'=':
switch(temp_first)
{
case'=':
pri='=';
break;
case'(' :
printf("\n\t Expression form error\n");
exit(-1);
default :
pri='>';
}
break;

default:
{
printf("\n\t Unknown operator \n");
pri = 0;
}
break;
}
return pri;
}

template <class t>
double CCOperator<t>::standardOpt(double temp_prefix,char temp_opt,double temp_postfix)
/* Pre: Already have two Nums and one Opt .
Post:Return the result of calculate. */
{
double temp_result;
switch(temp_opt)
{
case'+':temp_result=temp_prefix+temp_postfix;break;
case'-':temp_result=temp_prefix-temp_postfix;break;
case'*':temp_result=temp_prefix*temp_postfix;break;
case'/':
if(temp_postfix != 0)
{
temp_result=temp_prefix/temp_postfix;cout << temp_result;

}
else
{
printf("\n\t Calculate error \n");
}
break;
default:
{
printf("\n\t Unsupport operator \n");
break;
}
}
return temp_result;
}

template <class t>
bool CCOperator<t>::isOpt(char c)
{
switch(c)
{
case '+':
case '-':
case '*':
case '/':
case '(':
case ')':
case '=':
return true;
default:
return false;
}
}

bool doCalculate()
{
CCStack<double> stackSZ;
CCStack<char> stackZF;
CCOperator<double> calculatorOpt;

char temp_opt;
char a1,a2,a3;//Temporary Operation Saver.
double temp_number;                 //Temporary Number Saver.
double temp_prefix,temp_postfix;    //Temporary Opt Prefix(Number),Postfix(Number) Saver.
double temp_final;                  //Temporary Midway Final Saver.
double final;                       //The Final Calculate Result.
char temp_c;                        //Temporary Get One Char.
char convert_str2double[100];       //Use For Convert String To Double.
int judge=0;                        //The Currently Digit Saver.

stackZF.push('=');
temp_c=getchar();  //Get The First Char.

judge++;
stackZF.getTop(temp_opt);   // Get the Top Element Of the StackZF.
while(temp_c != '=' || temp_opt != '=')
{
if(calculatorOpt.isOpt(temp_c)) // Judge "temp_c" is Opt or not.
{
switch(calculatorOpt.compareOpt(temp_opt,temp_c)) // Return The PRI State: ">" , "<" or "=".
{
case '<': //Top Element PRI < temp_c.
stackZF.push(temp_c);
temp_c=getchar();
stackZF.getTop(temp_opt);
break;
case '='://Shuck Off The "( )" And Calculate "temp_final".
stackZF.pop(temp_opt);
stackZF.getTop(temp_opt);
temp_c=getchar();
break;

case '>'://Pop From the stackZF And stackSZ and Do Calculate.
if(temp_opt=='+'||temp_opt=='-'||temp_opt=='*'||temp_opt=='/')
{
char a1,a2,a3;
stackZF.pop(a1);
stackSZ.pop(a2);
stackSZ.pop(a3);
temp_opt = a1;
temp_postfix = atof(&a2);
temp_prefix = atof(&a3);
temp_final=calculatorOpt.standardOpt(temp_prefix,temp_opt,temp_postfix); //Calculate Out The temp_final.
stackSZ.push(temp_final);
stackZF.getTop(temp_opt);
break;
}
else
{
break;
}
}
}
else if((temp_c>='0' && temp_c<='9') || temp_c=='.') //Combination The Number(Double)
{
int i=0;
do
{
convert_str2double[i]=temp_c;
i++;
temp_c=getchar();
}while((temp_c<='9' && temp_c>='0') || temp_c=='.');
convert_str2double[i]=0;
temp_number=atof(convert_str2double); //Use The Function atof() to Convert A String Var To A Double One.
stackSZ.push(temp_number);
}
else
{
//ERROR
}
}
char a4;
stackSZ.getTop(a4);
final = atof(&a4);

printf("\nResultÃ¯Â¼Âš%15.15f",final);

return 0;
}
int main()
{
doCalculate();
return 0;
}
0

Commented:
The expression you input should like this ,
3/(1+2)=
you must input equal sign at last
0

Commented:
you must have some concept about template, look at http://www.iis.sinica.edu.tw/~kathy/vcstl/templates.htm

Now I talk about the core algorithm.
For an instance ,the expression is "6*(2+5/1)-4*3="

read char                       stack1(double value)                stack2(sign)                description
6                                     6                                                                                    push 6 into stack1
*                                      6                                                *                                 push * into stack2
(                                      6                                                *(                                push ( into stack2
2                                     6,2                                             *(                                push 2 into stack1
+                                     6,2                                            *(+                               push + into stack1
5                                    6,2,5                                         *(+                                push 5 into stack1
/                                     6,2,5                                         *(+/                               push / into stack2
1                                    6,2,5,1                                      *(+/                               push 1 into stack1
)                                     6,2                                           *(+                                do 5/1, stack1&stack2 pop
6,2,5                                        *(+                                 result 5 push into stack1
6                                              *(                                  do 2+5,stack1&stack2 pop
6,7                                           *(                                   result pushed into stack1
6,7                                           *                                    stack2 pop (
-                                                                                                                          do 6*7, stack1&stack2 pop
42                                                                                 result pushed into stack1
42                                            -                                    push - into stack2
4                                    42,4                                         -                                    push 4 into stack1
*                                     42,4                                        -*                                    push * into stack2
3                                    42,4,3                                     -*                                    push 3 into stack1
=                                    42                                           -                                      do 4*3,stack1&stack2 pop
42,12                                      -                                      result pushed into stack1
do 42-12,    end
0

Author Commented:
thank you very much. But whenever i enter an expression with = sign , it loops for ever and it doesn't show the answer. Is everything look fine in my code ?
0

Commented:
>>template <class t>
>>bool CCStack<t>::getTop(char &item) const      // bool CCStack<t>::getTop(t &item) const
>>{

>>    if(top > base)
>>    {
>>        item = *(top-sizeof(char));                      // item = *(top-sizeof(t));
>>    }
>>    else
>>    {
>>        return false;
>>    }
>>    return true;
>>}

It's wrong to use char type, look at my sample code.
Template is a more abstract concept than class, if you use char type,
when you declare double stack ,  the top pointer in your stack won't move correctly.
As the double type contains 4 bit,but char type only contains 1 bit.

You can try compiling my sample code and read it in detail.
0

Commented:
>>As the double type contains 4 bit,but char type only contains 1 bit.
Not bit,but byte.
0

Commented:
>>>>As the double type contains 4 bit,but char type only contains 1 bit.
>>>>Not bit,but byte.

A double has a size of 8 bytes.

>>>> accept the input as a character string

The doCalculate doesn't seem to be well-defined. It is mixing up user input with input parsing. From your requirements you should get the user input as char string. It is not required that you ask for each single char while doing the calculation. I would recommend to move the user input into main and pass the input string to doCalculate.

#include <string>
using namespace std;

int main()
{
while (true)
{
string input;
getline(cin, input);
if (input.find_first_of("Qq") == 0)
break;
double d  = doCalculate(input);
if (d == DBL_MIN)
{
cout << "[" << input << "], wrong syntax" << endl << endl;
continue;
}
cout << input " << " = " << d << endl << endl;
}
return 0;
}

The doCalulation would have prototype

double doCalculate(const string& input);

Regards, Alex
0

Commented:
>>A double has a size of 8 bytes.
yes, you are right.
.
>>The doCalculate doesn't seem to be well-defined. It is mixing up user input with input parsing. From >>your requirements you should get the user input as char string. It is not required that you ask for >>each single char while doing the calculation. I would recommend to move the user input into main and >>pass the input string to doCalculate.
Good suggestion.
0

Author Commented:
would it make sense to change the pop() and and push() methods from char to template t also ?

bool CCStack<t>::push(const char &item)             // use template instead here
{
if(!isFull())
{
*top = item;
top = top+sizeof(char);                        // change this also from char
}
return true;
}

template <class t>
bool CCStack<t>::pop(char &item)
{
if(!isEmpty())
{
top = top-sizeof(char);
item = *top;
}
return true;
}
0

Commented:
>>would it make sense to change the pop() and and push() methods from char to template t also ?
yeah, the code of stack is okay, isn't neccessary to be modified by yourself, just use it.
0

Author Commented:
Thank you very much for helping me
0
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.