1. ## Expression Evaluator

I want to write a calculator that reads an expression from user input computes the expression and display the result correct to 3 decimal points. The expression is evaluated from left to right.
I really don't know how to get started, please give a help. ^^

for example,

user input 15+3/2
output will be 16.500

user input 5*2.0^3+(1+4)*5
output will be 65.000

user input 3.5+2x=7.5
output will be 2
The calculator can solve x.

user input 15+-5.20
output will be 9.800

Please give me a help, thank you so much.

2. some pseudocode to get you going...

1) get the input from user using fgets(). Remember to replace the newline in the buffer with a null char.If you are not sure about this look up fgets() in your helpfiles or texts.
2) parse the string into tokens
3) work out the precedence of each token.Then I would use a stack to push them in order of precedence from least to most.
4) pop the tokens off the stack evaluating as necessary.
5) print the result.

try and code it yourself and come back if you are stuck.

3. ## How ?

I want to ask how to work out the precedence of each token,
it seems difficult to me.^^

work out the insides of parentheses first. From there you know to do division and multiplication before addition and subtraction etc. If you think about it a bit and i suspect you haven't too much or there would be some code posted for us to peruse, you will see that the problem is not too hard.

5. Do i need to use array in my program?

and how to extract the numbers?

for example, 3+5-(-1)
how to extract "+" and "-1" ??

thanks.

6. One of the things that ........ me off so bad is the fact that these questions are asked EVERY WEEK! Some times EVERY DAY. Some times MORE THAN ONCE A DAY! BY THE SAME PERSON!

Most of these questions could be answered if they spent a few minutes looking at previous posts. But hell, most people don't even read the very top post that says "READ THIS FIRST". I give up.

I refuse to answer any homework related question that doesn't present code, or understandable pseudocode.

Quzah.

7. The following way isn't the easiest one, but it is more "official" (if quzah is right and this is a homework).

some usefull thoughts:
1. you can write an expression in 3 ways:
a. the symbols between the numbers. (e.g. 5+7)
b. the symbols before the numbers. (e.g. +57)
c. the symbols after the numbers. (e.g. 57+)

2. An example about the third way:
5 + 7 - 3 / 2
5.7+3.2/- (using . as separator for the numbers)

3. The third way is very usefull for us.
(but you have to use a symbol that separates the numbers)
Why is it so usefull?
Because if the expression is written this way, the operations have to be executed left to right. (no matter if the operation is + , - , * or anything else and it has no () )

So if we have a stack, we have just to put a the numbers in the stack until we find an operator. Then we execute the operation using the 2 numbers who are in the top of the stack. When the expression ends the stack has only one number, the result.
(about the arrays: you can implement the stack with an array)

You have to write also some code for the convertion of the expression.

I propose this solution because it is very difficult to do something wrong computing the expression if the expression is written in the third way.

Does anybody knows how the 3 ways of writing the expression are in english?

8. It's very easy.

You have a function called Evaluate(long start, long stop, char* expr)

In that function, you first test if the expression is enclosed in parathesis. Count the paranthesis pairs and check if it's equal to 1. Then check if the character at expr[start] is '(' and the character at expr[stop] is ')'. If all that is true, the expression is enclosed into paranthesis. To remove the paranthesis, just add one to start and subtract one from stop. Loop this procedure until there aren't any parathesis left.

Then you walk through the string from start to stop. If you find a '(' you increase a paranthesis counter. If you find an operator and the paranthesis counter is 0 you test if the operator has lower significans than the last found operator. If it does, set it as the last found operator and save the position. If you find a ')' you decrease the paranthesis counter.

When you have done that, you'll probably have an operator you can play with. If you have an operator, call Evaluate() for both sides of the operator like this:

float a = Evaluate(start, op_pos-1, expr);
float b = Evaluate(op_pos+1, stop, expr);

Then check which operator you have found. Something like this:

switch(op_found)
{
case Plus:
return a+b;

case Minus:
return a-b;

//etc...
}

If you haven't got an operator, try to evaluate the expression as a constant or a variable and return the value of that.

If you need unary operators, you'll have to have a flag when you search for operators which tells if there has been any non-white characters since the last operator. If there haven't been non-white characters, any found operator should be ignored. Then you check for unary operators later by simply check what the first character is and if there is an unary operator, do like this:

1. Call Evalute(start+1,stop,expr)
2. Process the return with the operator. It can be '-', '!' or anything.
3. Return the processed value.

Isn't it simple? (Sorry for my bad explanations)

9. Okay, I wrote this in a minute. Copy and paste:

PHP Code:
``` #include <stdio.h> #include <string.h> #include <stdlib.h> #include <math.h> typedef enum Ops {  None,  Plus,  Minus,  Multiply,  Divide,  Power } OPS; long signif[] = {  0xFFFFFFFF,  10,  10,  11,  11,  12 }; typedef struct _constants {  char* symb;  long double value; } CONSTANTS; CONSTANTS constants[] = {  {"pi", 3.14159265358979323846264338327950} }; long double Evaluate(long start, long stop, char* expr); int main() {   char buffer[256];   long c;   do   {    printf("Enter expression to evaluate: ");    scanf("%s", buffer);    printf("Result: %f \n\n", (float)Evaluate(0, strlen(buffer)-1, buffer));        printf("Again? (1/0)");    scanf("%d", &c);   } while(c);      return 0; } long double Evaluate(long start, long stop, char* expr) {  OPS op_found;  OPS op_last = None;  unsigned long op_cursign = 0xFFFFFFFF;  long op_pos;  long parnest, parpair;  long curpos;  bool nonwhite;  //Remove enclosing whitespaces paranthesis  while(1)  {   //Remove enclosing white spaces   while(start <= stop)   {    if(expr[start] != ' '    && expr[start] != '\t'    && expr[start] != '\n'    && expr[start] != '\r') break;        start++;   }      while(stop >= start)   {    if(expr[stop] != ' '    && expr[stop] != '\t'    && expr[stop] != '\n'    && expr[stop] != '\r') break;        stop--;   }      if(start > stop)   {    printf("\nWarning: Empty expression interpreted as 0\n");    return 0;   }      //Remove enclosing parathesis   parnest = 0;   parpair = 0;   for(curpos = start; curpos <= stop; curpos++)   {    if(expr[curpos] == '(')    {     parnest++;    } else if(expr[curpos] == ')')    {     parnest--;     if(parnest == 0) parpair++;    }   }      if(expr[start] == '(' && expr[stop] == ')' && parpair == 1)   {    start++;    stop--;   } else break; //Break if there are no more paranthesis  }    //Search for operators    nonwhite = false;  parnest = 0;  op_cursign = 0xFFFFFFFF;  op_last = None;  for(curpos = start; curpos <= stop; curpos++)  {   if(parnest == 0) // Are we in paranthesis   {    op_found = None;    if(nonwhite)    {     switch(expr[curpos])     {      case '+':       op_found = Plus;       break;      case '-':       op_found = Minus;       break;      case '*':       op_found = Multiply;       break;      case '/':       op_found = Divide;       break;      case '^':       op_found = Power;       break;     }    } else    {     switch(expr[curpos])     {      //Interpret the operators as white spaces      case '+':      case '-':      case '*':      case '/':      case '^':            case ' ':      case '\t':      case '\n':      case '\r':       break; //Ignore white spaces      default:       nonwhite = true;     }    }    if(op_found != None)    {     nonwhite = false;     if(signif[op_found] <= op_cursign)     {      op_cursign = signif[op_found];      op_last = op_found;      op_pos = curpos;     }    }   }   if(expr[curpos] == '(')   {    parnest++;   } else if(expr[curpos] == ')')   {    parnest--;   }  }  if(parnest != 0)  {   printf("\nError: Parenthesis nesting error!\n");   return 0;  }    //Did we find any operators?  if(op_last != None)  {   long double a, b;       a = Evaluate(start, op_pos - 1, expr);   b = Evaluate(op_pos + 1, stop, expr);   switch(op_last)   {    case Plus:     return a+b;    case Minus:     return a-b;      case Multiply:     return a*b;         case Divide:     return a/b;         case Power:     return pow(a, b);   }   return true;  }  //Check for unary operators  switch(expr[start])  {   case '!':    return (Evaluate(start + 1, stop, expr) == 0);   case '-':    return -Evaluate(start + 1, stop, expr);  }  //Put in a null terminator  expr[stop+1] = 0; //This is pretty safe even though it may not look like that    //Check if the value matches any constants  for(long i = 0; i < sizeof(constants)/sizeof(CONSTANTS); i++)  {   if(strcmpi(&expr[start], constants[i].symb) == 0)   {    return constants[i].value;   }  }    //Check if the expression is a function  for(long i = start; i < stop; i++)  {   if(expr[i] == '(')   {    expr[i] = 0;    if(!strcmpi(&expr[start], "cos"))     return cos( Evaluate(i+1, stop-1, expr) );    else if(!strcmpi(&expr[start], "sin"))     return sin( Evaluate(i+1, stop-1, expr) );    else if(!strcmpi(&expr[start], "tan"))     return tan( Evaluate(i+1, stop-1, expr) );    else if(!strcmpi(&expr[start], "exp"))     return exp( Evaluate(i+1, stop-1, expr) );    else if(!strcmpi(&expr[start], "sqrt"))     return sqrt( Evaluate(i+1, stop-1, expr) );    else    {     printf("\nError: Unidentified function: %s\n", &expr[start]);     return 0;    }   }  }    //No matching constants. Evaluate as a literal  return atof(&expr[start]); }  ```

10. Thank you very much Gliptic,