-5

i want make math operation with one button and textbox , when type on textbox operation like 25+5+-10+7 and press on button show me result i am trying do this but i can not. in this code i make for each char in textbox and i want store 25 in firstvalue parameter and + in op parameter and 5 in secondvalue parameter and make operation 25+5=30 and store it in firstvalue parameter and store +- in op , 10 in secondvalue and make operation ,store it in firstvalue ....and so on until length of string . but i do not know where and how store second value

private void button1_Click(object sender, EventArgs e)
    {
        string allValue = textBox1.Text;
        int firstValue=0;
        int secondValue=0;
        string first = string.Empty;
        string op = string.Empty;


        foreach (char item in allValue)
        {
            if (char.IsNumber(item))
            {
                first += item;

            }

            else if(item=='+' || item=='-' || item=='*' || item=='/')
            {
                firstValue = Int32.Parse(first);
                op += item;
                first = "";

                switch (op)
                {
                    case "+":
                        firstValue = firstValue + secondValue;
                        break;
                    case "-":
                        firstValue = firstValue - secondValue;
                        break;
                    case "+-":
                        firstValue = firstValue +- secondValue;
                        break;
                    case "*":
                        firstValue = firstValue * secondValue;
                        break;
                    case "/":
                        firstValue = firstValue / secondValue;
                        break;

                }
            }
        }


        MessageBox.Show(firstValue.ToString());
    }
Asmaa Mohamed
  • 113
  • 1
  • 10
  • 1
    There are libraries (and probably examples online) that would make this problem extremely trivial. – Broots Waymb Oct 21 '15 at 18:14
  • The NCalc library is one : http://ncalc.codeplex.com/ – Fᴀʀʜᴀɴ Aɴᴀᴍ Oct 21 '15 at 18:14
  • There's quite a couple problems with this approach it seems... Mainly, it's a foreach loop that blindly loops through which means it doesn't take in to count the order of operations. – General Charismo Oct 21 '15 at 18:19
  • You should do things step by step and make sure that each bit works, rather than continue adding code until getting a bug. Also this is not how you should ask in SO: you have to properly understand the problem and include only relevant parts of your code (not everything by expecting someone to debug it). Other than that, I think that this is a nice exercise to get used to C# (and even to learn programming). Using libraries? In general with .NET? For what? If what you want is simple (just adding/subtracting), you might do it by your own. If it is difficult, there wouldn't any library.... – varocarbas Oct 21 '15 at 18:28
  • ... math parsing is something which can become really complex. Libraries are meant for simple (and generic) tasks. Although this is up to you. – varocarbas Oct 21 '15 at 18:33
  • i suggest you use split method instead instead of taking characters one by one – M.kazem Akhgary Oct 21 '15 at 18:59

4 Answers4

2

If you want to parse the string from beginning to end and do the calculations during the parsing, then you can't do the calculation between two values until you have both operands. That means that you have to wait until you find the second operator (or the end of the string) until you can do the calculation for the first operator.

When you parse the number, put that in the secondValue variable. If it's the first value then just move it to firstValue and continue to get another value, otherwise do the calculation with the two values that you have according to the previous operator.

To include the last calculation you can loop one step more than the last character in the string. That allows your loop to run one more time after the last value, and you can do that last calculation. It requires a few more checks though, so that you don't actually try to read from that position outside the string.

To handle negative values you should include that in the value, not using a +- operator. Otherwise you would also need --, *- and /- operators.

Example (not tested):

private void button1_Click(object sender, EventArgs e) {
  string allValue = textBox1.Text;
  int firstValue = 0;
  int secondValue = 0;
  string second = string.Empty;
  string op = string.Empty;

  for (int i = 0; i <= allValue.Length; i++) {
    if (i < allValue.Length && (Char.IsNumber(allValue[i]) || (char == '-' && second.Length == 0))) {
      second += allValue[i];
    } else if (i == allValue.Length || "+-*/".indexOf(allValue[i]) != -1) {
      secondValue = Int32.Parse(second);
      if (op.Length > 0) {
        switch (op) {
          case "+": firstValue += secondValue; break;
          case "-": firstValue -= secondValue; break;
          case "*": firstValue *= secondValue; break;
          case "/": firstValue /= secondValue; break;
        }
      } else {
        firstValue = secondValue;
      }
      if (i < allValue.Length) {
        op = allValue[i].ToString();
      }
      second = "";
    } else {
      // illegal formula
    }
  }
  MessageBox.Show(firstValue.ToString());
}

Note: This calculates strictly from left to right and does not handle priority, e.g. 1+2*3 is evaluated as (1+2)*3, not the 1+(2*3) that is normally used.

Guffa
  • 687,336
  • 108
  • 737
  • 1,005
1

You can use the NCalc library. You would use it like this:

NCalc.Expression e = new NCalc.Expression(textBox1.Text);
double value = e.Evaluate();
// Next, do something with your evaluated value.
Fᴀʀʜᴀɴ Aɴᴀᴍ
  • 6,131
  • 5
  • 31
  • 52
  • This is not a valid answer here. Not even a valid answer to "how should I parse an equation"? It might be an answer to "I don't know almost any programming, don't want to learn and am interested in adding up two numbers right away, what should I do?". By bearing in mind that recommending a library is offtopic in SO, do you think that actually recommending a library (to a person not even asking for such a thing; not even clearly defining the final goal) is on-topic? – varocarbas Oct 21 '15 at 18:35
  • i am sorry , this library really solved my problem but i want solve it by programming – Asmaa Mohamed Oct 21 '15 at 18:46
1

Doing all the things from scratch is not easy. In my simplified answer I'll presume your operators are only +-*/ (including their precedence).

Reference: How to evaluate an infix expression in just one scan using stacks?

First you should parse the input string... My way would be

public enum TokenType
{
    Operator,
    Operand
}

public class Token
{
    public string Value { get; set; }
    public TokenType Type { get; set; }

    public override string ToString()
    {
        return Type + "   " + Value;
    }
}

IEnumerable<Token> Parse(string input)
{
    return Regex.Matches(input, @"(?<value>\d+)|(?<type>[\+\-\*\/\(\)])").Cast<Match>()
                .Select(m => m.Groups["value"].Success
                        ? new Token() { Value = m.Groups["value"].Value, Type = TokenType.Operand }
                        : new Token() { Value = m.Groups["type"].Value, Type = TokenType.Operator });
}

This Parse method will return all the operators and operands in your expression.

The next step would be to evaluate the expression using a stack

Token Exec(Stack<Token> operatorStack, Stack<Token> operandStack)
{
    var op = operatorStack.Pop();
    var t1 = operandStack.Pop();
    var t2 = operandStack.Pop();

    switch (op.Value)
    {
        case "+": return new Token() { Value = (int.Parse(t1.Value) + int.Parse(t2.Value)).ToString(), Type = TokenType.Operand };
        case "-": return new Token() { Value = (int.Parse(t2.Value) - int.Parse(t1.Value)).ToString(), Type = TokenType.Operand };
        case "*": return new Token() { Value = (int.Parse(t1.Value) * int.Parse(t2.Value)).ToString(), Type = TokenType.Operand };
        case "/": return new Token() { Value = (int.Parse(t2.Value) / int.Parse(t1.Value)).ToString(), Type = TokenType.Operand };
    }
    return null;
}

int Eval(string input)
{
    var tokens = Parse(input);

    var operatorStack = new Stack<Token>();
    var operandStack = new Stack<Token>();
    var precedence = new Dictionary<string, int>() { { "+", 0 }, { "-", 0 }, { "*", 1 }, { "/", 1 } };

    foreach (var token in tokens)
    {
        if (token.Type == TokenType.Operand) operandStack.Push(token);
        if (token.Type == TokenType.Operator)
        {

            while (operatorStack.Count > 0 && precedence[operatorStack.Peek().Value] >= precedence[token.Value])
            {
                operandStack.Push(Exec(operatorStack, operandStack));
            }
            operatorStack.Push(token);
        }
    }

    while(operatorStack.Count>0)
    {
        operandStack.Push(Exec(operatorStack, operandStack));
    }

    return int.Parse(operandStack.Pop().Value);
}

You can test your code now.

int r1 = Eval("25 - 5");
int r2 = Eval("25 - 5*2");
int r3 = Eval("25 - 5 + 3*2");
int r4 = Eval("25/5 + 7*3");
int r5 = Eval("25/5 + 7*3 + 2");
int r6 = Eval("25/5 + 7*3 * 2");
Community
  • 1
  • 1
Eser
  • 12,346
  • 1
  • 22
  • 32
1

Would this work for you? As mentioned in earlier answers this does not pay regard to the order of operations and there is a lot of other error checking that should likely be done.

using System.Text.RegularExpressions;

private void button1_Click(object sender, EventArgs e)
{
    MatchCollection values = Regex.Matches(textBox1.Text, "[0-9]+");
    MatchCollection operations = Regex.Matches(textBox1.Text, @"[\/\*\+-]");
    if (values.Count == operations.Count + 1)
    {
        int total = int.Parse(values[0].Value);
        if (operations.Count > 0)
        {
            for (int index = 1; index < values.Count; index++)
            {
                int value = int.Parse(values[index].Value);
                switch (operations[index - 1].Value)
                {
                    case "+":
                        total += value;
                        break;
                    case "-":
                        total -= value;
                        break;
                    case "/":
                        total /= value;
                        break;
                    case "*":
                        total *= value;
                        break;
                }

            }
        }
        MessageBox.Show(total.ToString());
    }
}
Clay Ver Valen
  • 1,033
  • 6
  • 10