hey guys,

I have written a calculator program in C++. It suppose to get the input from the user which is a string. Some thing like ((5+3)/2)*5. If you input that expression it gives 20, which is the correct answer. The problem i am having is that it cannot compute the expression if i input a negative number. like if i input ((5+3)/-2)*5 or ((5+3)/2)*-5, it will throw an error. I really cant seem to figure out where the problem is.

If some1 can tell me what to change to fix the problem, it would be a great help

here is the code...

#include<iostream>
#include<sstream>
#include<string>
#include<cctype>
#include<cmath>
using namespace std;

enum {PLUS='+',MINUS='-',MUL='*',DIV='/'};

double Value_Of_Num(string &Expr)

{
   istringstream is(Expr);
   double value=0.0;
   is >> value;
   return value;
}

double Value_Of_Expr(string &Expr)

{
  int i=0,p=0,pos_mul=0,pos_div=0;

   if(Expr.at(0)=='('&&Expr.at(Expr.length()-1)==')')
   {
       for(i=0;i < Expr.length();i++)
	   {
                   
        if(Expr.at(i)=='(') p++;
           else if(Expr.at(i)==')') p--;
           if(p==0) break;
        
	   }

       if(i==Expr.length()-1)
       return Value_Of_Expr(Expr.substr(1,Expr.length()-2));
   }

   for(i=0;i < Expr.length();i++)
   {
       if(Expr.at(i)=='(') p++;
		else if(Expr.at(i)==')') p--;
		else if(p==0&&ispunct(Expr.at(i)))
		{
        
		    switch(Expr.at(i))
			{
				case PLUS:
				return Value_Of_Expr(Expr.substr(0,i))+Value_Of_Expr(Expr.substr(i+1,Expr.length()-i-1));
				case MINUS:
				return Value_Of_Expr(Expr.substr(0,i))-Value_Of_Expr(Expr.substr(i+1,Expr.length()-i-1));
				case MUL: pos_mul=i; break;
				case DIV: pos_div=i; break;
      
			}
		}
   }

  if(pos_mul)
  return Value_Of_Expr(Expr.substr(0,pos_mul))*Value_Of_Expr(Expr.substr(pos_mul+1,Expr.length()-pos_mul-1));
  
  if(pos_div)
  return Value_Of_Expr(Expr.substr(0,pos_div))/Value_Of_Expr(Expr.substr(pos_div+1,Expr.length()-pos_div-1));
  
  return Value_Of_Num(Expr);
}


// several important validation checks on the input
bool Check(string input_string)
{

   for (int r = 0; r < input_string.length(); r++)
   {
       if((input_string[r]=='+')||(input_string[r]=='-'))
       {
           if((input_string[r+1]=='+')||(input_string[r+1]=='-'))
           {
               return false;
           }
       }
   }
   string array="0123456789+-*/()";
   int count=0;
   for (int s=0; s < input_string.length(); s++)
   {
       for(int z=0; z < array.length(); z++)
       {
           if(input_string[s]==array[z])
           {
              count++;
           }
       }
   }
   if (count == input_string.length())
   {
     return true;
   }
   else
   {
     return false;
   }
}

int main()

{
string expression;
string rerun = "y";

	cout << "                   Welcome to Rajat's calculator!" << endl;
	cout << "" << endl;
	cout << "" << endl;
	cout << "With this calculator, your problem solving is made simple." << endl;
	cout << "You do not have to calculate each part of an expression one at a time \nlike you do with you simple calculators." << endl;
	cout << "All you have to do is simply input an expression \nand the calculator will give you the answer." << endl;

do
{
	cout << "" << endl;
    cout << "Enter your expression:";
    cin >> expression;
  
  if(Check(expression)==true)

  {
     cout << Value_Of_Expr(expression)<<endl;
  }
  else
  {
      cout << "" <<endl;
      cout << "Error in the input" << endl;
  }
cout << "Would you like to solve another expression? If yes, the press \"y\" and enter or press \"n\" if you want to quit." << endl;
cin >> rerun;

}while (rerun == "y");

return 0;
}

modify the signature of these two functions:

double Value_Of_Num( const string &Expr ) ;
double Value_Of_Expr( const string &Expr ) ;

or a comforming compiler will give you errors.
you can't initialize a reference to a modifiable value with an anonymous temporary (deemed to be a constant).

> The problem i am having is that it cannot compute the expression if i input
> a negative number. like if i input ((5+3)/-2)*5 or ((5+3)/2)*-5
hint: it also baulks at positive numbers with a unary +.
eg. ((5+3)/+2)*5 or ((5+3)/2)*+5

modify the signature of these two functions:

double Value_Of_Num( const string &Expr ) ;
double Value_Of_Expr( const string &Expr ) ;

or a comforming compiler will give you errors.
you can't initialize a reference to a modifiable value with an anonymous temporary (deemed to be a constant).

> The problem i am having is that it cannot compute the expression if i input
> a negative number. like if i input ((5+3)/-2)*5 or ((5+3)/2)*-5
hint: it also baulks at positive numbers with a unary +.
eg. ((5+3)/+2)*5 or ((5+3)/2)*+5

hey thnx for the relpy...
I made the change but it didnt work....im very new to this and i dont understand much of this. I got a lot of help from people in writing this code. I would have just asked those people for help again as they know what i need 2 do exactly. But unfortunately those people arent available anymore.

If you can just correct the code and paste it here it would a great help as i dont have much time left. This assignment is due 2 days. thnx

I haven't read your code, but I would guess that you are not tokenizing properly...

I would take a finite state machine (FSM) approach to solving this problem...reading in input character by character, and calling routines based on the input...(somewhat of a C influence I suppose).

With that in mind, you really only have a few tokens to consider, depending on how complex you are making this...

That is, you should account for a number state (if you read a number token), and a symbol state (reading a symbol). So for example, if you read in a character "3", you need to call a routine that peeks at the next character. If it is a number, you need to put the numbers together (i.e. if it is a "5", then you need to make the whole number 35). If it is a symbol, then you move to a different routine that parses symbols (i.e. brackets, operators, etc).

I apologize if that sounds confusing....gotta run!

The problem will be solved if you write the following:

case PLUS:
if(expr.substr(0,i) != "")
return evaluateExpr(expr.substr(0,i))+evaluateExpr(expr.substr(i+1,expr.length()-i-1));
else
return evaluateExpr(expr.substr(i+1,expr.length()-i-1));
case MINUS:
if(expr.substr(0,i) != "")
return evaluateExpr(expr.substr(0,i))-evaluateExpr(expr.substr(i+1,expr.length()-i-1));
else
return -evaluateExpr(expr.substr(i+1,expr.length()-i-1)); //the number is negative

This article has been dead for over six months. Start a new discussion instead.