# Thread: can someone help me to write a calculator in C++ using stack?

1. ## calculator which can calculate cosine and log and simple operation?

Code:
```/*
A Simple expression evaluator which uses infix to postfix notation
to evaluate an expression. Still has bugs which need to be fixed!!!
V.0.2 -> To handle operator anomolies such as:
-7*-4    and  2*(-5+6)
*/

#include <iostream>
#include <sstream>
#include <string>
#include <stack>
#include <vector>
#include <math.h>

using namespace std;
//function declarations
void Convert(const string & Infix, string & Postfix);
bool IsOperand(char ch);
bool TakesPrecedence(char OperatorA, char OperatorB);

string Change_me(string);
string Insert_comma(string);
bool Check_valid(string);
double Eval(string[]);
void Next(string);

int main()
{

do
{
string Infix, Postfix; // local to this loop

cout <<"\n    Enter your expression with No spaces!\n\n";
cout <<"     e.g. (4+2)*3/2 "<< endl;
cout <<"    Unknown variables such as 'a' and 'x' are not allowed:\n\n>>";
cin >> Infix;

if(Check_valid(Infix)==true)
{

string temp;
temp = Change_me(Infix);
//cout<<temp;
//cin.get();

Convert(temp, Postfix);

cout << "The equivalent postfix expression is:" << endl
<<Insert_comma(Postfix);

string hold;
hold = Insert_comma(Postfix);

Next(hold);

cout << endl << "\nDo another (y/n)? ";
}
else
{
cout<<"***Syntax error***\n";
cout << endl << "Do another (y/n)? ";

}

return 0;
}

/* Given:  ch   A character.
Task:   To determine whether ch represents an operand (here understood
to be a single letter or digit).
Return: In the function name: true, if ch is an operand, false otherwise.
*/
bool IsOperand(char ch)
{
if (((ch >= 'a') && (ch <= 'z')) ||
((ch >= 'A') && (ch <= 'Z')) ||
((ch >= '0') && (ch <= '9')))
return true;
else
return false;
}

/* Given:  OperatorA    A character representing an operator or parenthesis.
OperatorB    A character representing an operator or parenthesis.
Task:   To determine whether OperatorA takes precedence over OperatorB.
Return: In the function name: true, if OperatorA takes precedence over
OperatorB.
*/
bool TakesPrecedence(char OperatorA, char OperatorB)
{
if (OperatorA == '(')
return false;
else if (OperatorB == '(')
return false;
else if (OperatorB == ')')
return true;
else if ((OperatorA == '^') && (OperatorB == '^'))
return false;
else if (OperatorA == '^')
return true;
else if (OperatorB == '^')
return false;
else if ((OperatorA == '*') || (OperatorA == '/'))
return true;
else if ((OperatorB == '*') || (OperatorB == '/'))
return false;
else
return true;

}

/* Given:  Infix    A string representing an infix expression (no spaces).
Task:   To find the postfix equivalent of this expression.
Return: Postfix  A string holding this postfix equivalent.
*/
void Convert(const string & Infix, string & Postfix)
{
stack<char> OperatorStack;
char TopSymbol, Symbol;
int k;

for (k = 0; k < Infix.size(); k++)
{
Symbol = Infix[k];
if (IsOperand(Symbol))
Postfix = Postfix + Symbol;
else
{
while ((! OperatorStack.empty()) &&
(TakesPrecedence(OperatorStack.top(), Symbol)))
{
TopSymbol = OperatorStack.top();
OperatorStack.pop();
Postfix = Postfix + TopSymbol;
}
if ((! OperatorStack.empty()) && (Symbol == ')'))
else
OperatorStack.push(Symbol);
}
}

while (! OperatorStack.empty())
{
TopSymbol = OperatorStack.top();
OperatorStack.pop();
Postfix = Postfix + TopSymbol;
}
}
/*---------------------------------------------
My function needed to tokenise the expression

--------------------------------------------*/

string Change_me(string my_string)
{

for(int i = 0; i <my_string.length(); i++)
{
if(isdigit(my_string[i])!=0)
{
if(isdigit(my_string[i+1])==0)
{
my_string.insert(i+1, "v");
//v is just an arbitary choice
//it could be any other letter
//but it has to be a LETTER

}
}
}
//Changed -7*-7 case
for (int i = 0; i <my_string.length(); i++)
{
if(my_string[i]=='-')
{
if((my_string[i-1]!='v')&&(my_string[i-1]!=')'))
{
my_string.replace(i,1,"y");
}
}
}

return my_string;
}

/*-----------------------------------------
My function needed to tokenise expression
-----------------------------------------*/
string Insert_comma(string my_string)
{
for(int i = 0; i <my_string.length(); i++)
{
if((my_string[i]=='*')||
(my_string[i]=='-')||
(my_string[i]=='/')||
(my_string[i]=='+')||
(my_string[i]=='^'))
{
my_string.insert(i+1, ",");
//Insert a comma after all
//found operators
}
else if(my_string[i]=='v')
{
my_string.replace(i,1,",");
//replace the v with a comma
//for clarity
}
}
//Changed
for (int i = 0; i <my_string.length(); i++)
{
if(my_string[i]=='y')
{
my_string.replace(i,1,"-");
}
}
return my_string;
}

/*-----------------------------------------
My function to check that no variables
were entered
-----------------------------------------*/
bool Check_valid(string my_string)
{
//Changed check that consecutive '+', '-'
//signs do not exist
for (int i = 0; i<my_string.length(); i++)
{
if((my_string[i]=='+')||(my_string[i]=='-'))
{
if((my_string[i+1]=='+')||(my_string[i+1]=='-'))
{
return false;
}
}
}

string array="0123456789+-*/()^";

int count=0;
for (int i=0; i<my_string.length(); i++)
{
for(int j=0; j<array.length(); j++)
{
if(my_string[i]==array[j])
{
count++;
}
}
}

if (count == my_string.length())
{
return true;
}
else
{
return false;
}

}

/*-----------------------------------
My function to actually evaluate
postfix expression
----------------------------------*/

void Next(string my_string)
{
vector <string> array;
string tempy;

int comma_count=0;
for (int a=0; a<my_string.length();a++)
{
if(my_string[a]==',')
{
comma_count++;
}
}

//Evaluate tokens using the "," as a delimiter
while (my_string.find(",", 0) != string::npos)
{
//lifted from the FAQ
//does the string have a comma in it?
size_t pos = my_string.find(",", 0);
tempy = my_string.substr(0, pos);
my_string.erase(0, pos + 1);
array.push_back(tempy); //store in vector
}

//array.push_back(my_string);//the last token is all alone

stack <string> my_stack;//initialise stack
string temp[100];
string ch;

for (int i=0; i<comma_count; i++)
{

string s;
s=array[i]; //make it easier to read

if ((s!="+")&&
(s!="*")&&
(s!="-")&&
(s!="/")&&
(s!="^"))
{
my_stack.push(s);
//push numbers onto the stack
}
else //i.e if it encounters an operator
{
my_stack.push(s);//push operator onto stack
temp[0]= my_stack.top();//store value
my_stack.pop(); //erase from the stack

temp[1]= my_stack.top();//store value
my_stack.pop();//erase from the stack

temp[2]= my_stack.top();//store value
my_stack.pop();//erase from the stack

double z;
z = Eval(temp);
ostringstream outs;  // Declare an output string stream.
outs << z;   // Convert value into a string.
ch = outs.str();

my_stack.push(ch);

}
}
cout<<ch;
cin.get();
}
/*------------------------------
My function to do the math:
Converts string to double
then back to string
------------------------------*/
double Eval(string temp[])
{
string a,b,c;
a=temp[2]; b=temp[0]; c=temp[1];
double x,y,z;
istringstream ins,inse;
ins.str(a);inse.str(c);
ins >> x;
inse >> y;

if (b=="+")
{
z = x + y;
return z;
}
else if (b=="-")
{
z = x - y;
return z;
}
else if (b=="*")
{
z = x * y;
return z;
}
else if (b=="/")
{
z = x / y;
return z;
}
else if (b=="^")
{
z = pow(x,y);
return z;
}
}```
I have found the code which can calculate +-*/^, but I want it to also to calculate cosine log, I don't know how to add cos and log to it, anyone can help me?

2. I haven't gone over the code, but it should be a simple matter of calling the functions cos and log10 functions from <cmath> (see CPlusPlus - cmath. Also, #include <cmath>, not <math.h>. As far as I know, it's always better to use the C++ headers when programming in C++.

Hope this helps