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

  1. #1
    Registered User
    Join Date
    May 2009
    Posts
    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);
    
    /*My functions I've added*/
    string Change_me(string);
    string Insert_comma(string);
    bool Check_valid(string);
    double Eval(string[]);
    void Next(string);
    
    int main()
    {
       
       char Reply;
    
       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);
             
             cout<<"\n\nThe answer is:";
             Next(hold);
     
             cout << endl << "\nDo another (y/n)? ";
             cin >> Reply;
            }
            else
            {
                cout<<"***Syntax error***\n";
                cout << endl << "Do another (y/n)? ";
                cin >> Reply;
                
            }       
              
          }while (tolower(Reply) == 'y');
    
       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 == ')'))
                OperatorStack.pop();   // discard matching (
             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?
    Last edited by anglin1024; 05-02-2009 at 01:04 AM.

  2. #2
    Registered User
    Join Date
    Mar 2008
    Posts
    71
    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

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. stack and pointer problem
    By ramaadhitia in forum C Programming
    Replies: 2
    Last Post: 09-11-2006, 11:41 PM
  2. Linked list Stack question
    By lyrick in forum C++ Programming
    Replies: 4
    Last Post: 09-23-2005, 06:23 AM
  3. Stack
    By planet_abhi in forum C Programming
    Replies: 2
    Last Post: 04-12-2003, 04:22 AM
  4. Stack functions as arrays instead of node pointers
    By sballew in forum C Programming
    Replies: 8
    Last Post: 12-04-2001, 11:13 AM
  5. stack make file problem
    By puckett_m in forum C Programming
    Replies: 2
    Last Post: 11-22-2001, 11:51 AM