6

Hi fellow programmers,

I am creating a calculator in C#

and I have a string variable math which contains 100 * 5 - 2

How can I display its output which is 498 in my console?

My code is this:

String math = "100 * 5 - 2"; 

Console.WriteLine(math);

Console.ReadLine(); // For Pause

So basically, what my code will give me is the string itself which 100 * 5 - 2

but I want it to give me 498 as a result.

Idea about this is pretty much appreciated.

Thanks

Nagaraj S
  • 12,563
  • 6
  • 30
  • 50
GM-Xile GM-Xile
  • 283
  • 1
  • 8
  • 21
  • Can you not store it as a string, and instead use int? – panoptical Feb 22 '14 at 05:22
  • 1
    Please search for "C# parse math expression" and make you question more concrete. If you don't know how to use search engines here is starting point http://stackoverflow.com/questions/234217/is-it-possible-to-compile-and-execute-new-code-at-runtime-in-net for parsing options. – Alexei Levenkov Feb 22 '14 at 05:22
  • Dijkstra's Shunting Yard algorithm may be of interest to you: http://en.wikipedia.org/wiki/Shunting-yard_algorithm – pcnThird Feb 22 '14 at 05:24
  • possible duplicate of [evaluate an arithmetic expression stored in a string (C#)](http://stackoverflow.com/questions/4620437/evaluate-an-arithmetic-expression-stored-in-a-string-c) – Anderson Green Feb 22 '14 at 05:49

3 Answers3

19

Regular Expression evaluation can be done using DataTable.Compute method (from MSDN) :

Computes the given expression on the current rows that pass the filter criteria.

Try this:

using System.Data;//import this namespace

 string math = "100 * 5 - 2";
 string value = new DataTable().Compute(math, null).ToString();
Antoine
  • 342
  • 1
  • 11
  • 16
Sudhakar Tillapudi
  • 24,787
  • 5
  • 32
  • 62
2

Simply try this

String math = (100 * 5 - 2).ToString(); 

I don't know, Why you want more complex? It's very easy ..

And if you want surely that,You can do that by using EvaluateExpression

public int EvaluateExpression(string math )
    {
       return Convert.ToInt32(math);
    }

........................

String math = "100 * 5 - 2"; 

int result = EvaluateExpression(math );

Console.WriteLine(result );

See this discussions

Evaluating string "3*(4+2)" yield int 18

Update:

If those values came from input textbox, then write this way

String math = txtCalculator.Text.Trim();

    int result = EvaluateExpression(math );

    Console.WriteLine(result );

And also you can find out some pretty answer from this discussion

Is it possible to compile and execute new code at runtime in .NET?

Update 2:

Finally I have tried this sample for you :

My full code for class library

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net;
using System.Text.RegularExpressions;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Xml.XPath;

public partial class _Default : Page
{
    protected void Page_Load(object sender, EventArgs e)
    {
        String math = "100 * 5 - 2";

        Console.WriteLine(Evaluate(math));
    }

    public static double Evaluate(string expression)
    {
        var xsltExpression =
            string.Format("number({0})",
                new Regex(@"([\+\-\*])").Replace(expression, " ${1} ")
                                        .Replace("/", " div ")
                                        .Replace("%", " mod "));

        // ReSharper disable PossibleNullReferenceException
        return (double)new XPathDocument
            (new StringReader("<r/>"))
                .CreateNavigator()
                .Evaluate(xsltExpression);
        // ReSharper restore PossibleNullReferenceException
    }
}
Community
  • 1
  • 1
Ramesh Rajendran
  • 32,579
  • 35
  • 130
  • 205
0

You can compile code from string at runtime and execute it:

using Microsoft.CSharp;
using System;
using System.CodeDom.Compiler;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;

namespace DynamicCalcTest
{
    class Program
    {
        static void Main(string[] args)
        {
            var result = new DynamicCalculator<double>("2 + 2 * 2").Execute();
        }
    }


    public class DynamicCalculator<T>
    {
        private MethodInfo _Method = null;

        public DynamicCalculator(string code)
        {
            _Method = GetMethodInfo(code);
        }

        public T Execute()
        {
            return (T)_Method.Invoke(null, null);
        }

        private MethodInfo GetMethodInfo(string code)
        {
            var tpl = @"
                public static class Calculator
                {{
                    public static double Calc()
                    {{
                        return {0};
                    }}
                }}";

            var finalCode = string.Format(tpl, code);

            var parameters = new CompilerParameters();
            parameters.ReferencedAssemblies.Add("mscorlib.dll");
            parameters.GenerateInMemory = true;
            parameters.CompilerOptions = "/platform:anycpu";

            var options = new Dictionary<string, string> { { "CompilerVersion", "v4.0" }     };

            var c = new CSharpCodeProvider(options);
            var results = c.CompileAssemblyFromSource(parameters, finalCode);

            var type = results.CompiledAssembly.GetExportedTypes()[0];
            var mi = type.GetMethod("Calc");
            return mi;
        }
    }
}
johnnyno
  • 578
  • 3
  • 13