Avatar billede thomas-k Nybegynder
08. august 2007 - 18:35 Der er 13 kommentarer og
1 løsning

Regnemaskine som kan regne med mere end 2 værdier

Jeg er meget ny til C#. Jeg prøver at lave en regnemaskine, og den virker også fint, dog kan jeg kun regne med 2 værdier. Dvs. jeg kan fx sige 2+2, men ikke 2+2+2. Nogle der kan hjælpe med det?

Det ville også være rart hvis der var noget try/catch sætninger, så man fx ikke kan skrive bogstaver, klikke på = tegnet når der ikke er indført tal m.m.
Avatar billede thomas-k Nybegynder
08. august 2007 - 18:35 #1
Dette er min kode:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;

namespace Regnmaskine
{
    public partial class Form1 : Form
    {


        int taltemp1;
        int taltemp2;
        string operatoren;

        public Form1()
        {
            InitializeComponent();
        }





        //0-9 knapper==========================================
        private void button_Click(object sender, EventArgs e)
        {
            Button a = (Button)sender;
            textBox1.Text += a.Text;

        }

        //Opratorer knap========================================
        private void operatorer_Click(object sender, EventArgs e)
        {


            Button operatorer = (Button)sender;
            operatoren = operatorer.Text;
            taltemp1 = int.Parse(textBox1.Text);
            textBox1.Clear();


        }


        //Cases=================================================
        private void ligmed_Click(object sender, EventArgs e)
        {
            Button ligmed = (Button)sender;
            taltemp2 = (int.Parse(textBox1.Text));
            int resultat = 0;


            switch (operatoren)
            {
                case "+":
                    resultat = taltemp1 + taltemp2;
                    break;
                case "-":
                    resultat = taltemp1 - taltemp2;
                    break;

                case "*":
                    resultat = taltemp1 * taltemp2;
                    break;

                case "/":
                    resultat = taltemp1 / taltemp2;
                    break;

                default:
                    MessageBox.Show("Indskrivnings fejl!");
                    break;
            }
            textBox1.Text = resultat.ToString();

        }







        //C knap===============================================
        private void buttonclear_Click(object sender, EventArgs e)
        {
            Button c = (Button)sender;
            textBox1.Clear();
            taltemp1 = 0;
            taltemp2 = 0;
            operatoren = "";
        }

        private void luk_Click(object sender, EventArgs e)
        {
            this.Close();
        }
    }
}
Avatar billede arne_v Ekspert
08. august 2007 - 18:42 #2
Du skal vel ogsaa kunne klare parenteser !

:-)

Der er grundliggende 2 loesninger:

1)  The hard way. Konverter streng til collection af tokens. Konverter den collection
    fra infix til postfix. Evaluer.

2)  Genvej. Som f.eks. at kalde JavaScripts eval funktion fra C#.
Avatar billede thomas-k Nybegynder
08. august 2007 - 18:59 #3
Ok, løsning 1 lyder som noget der kan bruges, men det er 2tal sort snak for mig. Kunne du uddybe den lidt.
Avatar billede arne_v Ekspert
08. august 2007 - 19:19 #4
Det er lidt svaert at forklare paa faa linier, men her er den meget korte version:

"2+2+2"
->
collection med tal 2, operator +, tal 2, operator +, tal 2
->
collection med tal 2, tal 2, operator +, tal 2, operator +

evaluering:
2
2 2
2 2 +
4
4 2
4 2 +
6
Avatar billede thomas-k Nybegynder
08. august 2007 - 19:29 #5
Ja, men hvordan hulen kan jeg skrive det på c# sprog ;-)
Avatar billede arne_v Ekspert
09. august 2007 - 03:07 #6
Nogle hundrede linier kode gør underværker ...

Prøv og start - og spørg så når du kører fast !
Avatar billede nielle Nybegynder
09. august 2007 - 09:43 #7
Her er en 3. mulighed (som dog smager lidt af arne_v's mulighed nr. 2).

===== Klassen Eval =====

using System;
using System.CodeDom.Compiler;
using System.Reflection;
using Microsoft.CSharp;

namespace e790825
{
    class Eval<T>
    {
        public Eval(string expression)
        {
            CreateAssembly(expression);
            ReflectOnAssembly();
        }

        private T _value;
        public T Value
        {
            get { return _value; }
        }

        private Assembly _evalAssembly;

        private void CreateAssembly(string expression)
        {
            string codeTemplate =
@"using System;
class EvalClass
{
    public static TYPE EvalMethod()
    {
        return EXPRESSION;
    }
}";

            // Indsæt retur-type og expression på det rigtige sted i kode-skabelonen.
            string code = codeTemplate.Replace("TYPE", typeof(T).ToString());
            code = code.Replace("EXPRESSION", expression);

            // Opret en compiler instans.
            CSharpCodeProvider provider = new CSharpCodeProvider();

            // Parametre til compileren.
            CompilerParameters cp = new CompilerParameters();
            cp.GenerateExecutable = false;  // Lav en DLL ...
            cp.GenerateInMemory = true;  // ... i memory (istedet for disk)
            cp.TreatWarningsAsErrors = false;

            // Kompilér koden.
            CompilerResults cr = provider.CompileAssemblyFromSource(cp, code);

            // Var der fejl i koden? Så er det nok expression den er gal med!
            if (cr.Errors.Count > 0)
                throw new ArgumentException("Error in expression.");

            // Gem det kompilerede resultat.
            _evalAssembly = cr.CompiledAssembly;
        }

        private void ReflectOnAssembly()
        {
            // Opret en pointer til klassen EvalClass.
            Type evalClass = _evalAssembly.GetType("EvalClass");

            // Opret en pointer til metoden EvalMethod
            MethodInfo evalMethod = evalClass.GetMethod("EvalMethod");

            // Kald EvalClass.EvalMethod.
            _value = (T) evalMethod.Invoke(null, null);
        }
    }
}

=====

Den bruges f.eks. sådan her:

using System;
using System.Collections.Generic;

namespace e790825
{
    class Program
    {
        static void Main(string[] args)
        {
            string expression = "2+2+2";

            try
            {
                Eval<int> eval = new Eval<int>(expression);
                Console.WriteLine(eval.Value);
            }
            catch (ArgumentException)
            {
                Console.WriteLine("Fejl i din expression: {0}", expression);
            }
        }
    }
}
Avatar billede arne_v Ekspert
10. august 2007 - 02:06 #8
Fordelen ved JavaScript er at man kun skal compile en gang.
Avatar billede nielle Nybegynder
10. august 2007 - 08:54 #9
Det er vel ikke direkte en ulempe at der skal kompiles flere gange - når det nu er programmet selv som gør det i baggrunden?
Avatar billede arne_v Ekspert
11. august 2007 - 05:28 #10
Eneste ulempe er performance.

Det er jo ikke ligefrem normalt at JScript er 1000 gange hurtigere end C#.
Avatar billede thomas-k Nybegynder
13. august 2007 - 20:06 #11
Nå, lidt forsinket her, men jeg anvendte dit forslag nielle. Takker for hjælpen. Smider du ikke et svar.
Avatar billede nielle Nybegynder
14. august 2007 - 07:14 #12
Svar :^)
Avatar billede arne_v Ekspert
15. august 2007 - 04:20 #13
Skræmmer navnet JavaScript ?
Avatar billede thomas-k Nybegynder
15. august 2007 - 17:25 #14
Ja, fordi jeg har kun snuset lidt til java script (copy-paste stil), samt c# er meget nyt for mig, så vil helst ikke blande det sammen da det var en skoleopgave.
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
IT-kurser om Microsoft 365, sikkerhed, personlig vækst, udvikling, digital markedsføring, grafisk design, SAP og forretningsanalyse.

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester