Laden...

Taschenrechner mit mehreren Rechnungen auf einmal auswerten

Erstellt von Asonger vor 7 Jahren Letzter Beitrag vor 7 Jahren 7.947 Views
A
Asonger Themenstarter:in
10 Beiträge seit 2014
vor 7 Jahren
Taschenrechner mit mehreren Rechnungen auf einmal auswerten

Hallo liebe Community des fröhlichen progen,

ich stehe vermutlich dick auf'm Schlauch!
Ich habe heute einen Taschenrechner programmiert, der aber nur mit Eingabe des Gleichheitszeichens mehrere Rechnungen zusammen rechnen kann.
Ich würde aber gerne mehrer durchführen wollen, ohne vorher noch das Gleichheitszeichen zu drücken.
bsp : "5+5-2*2 = 16" (Soll Punkt vor Strich nicht berücksichtigen)

Ich bin für jede Hilfe und jeden Lösungsvorschlag offen!

Ich bedanke mich im Voraus!
Mit freundlichen Grüßen, Ben.

using System;
using System.Windows.Forms;

namespace WindowsFormsApplication1
{
    public partial class Form1 : Form
    {
        
        
        

        public Form1()
        {
            InitializeComponent();
        }
        float num1, ans;
        int zähler;

        private void btnC_Click_1(object sender, EventArgs e)
        {
            float num1, ans;
            int zähler;
        }

        private void btnCE_Click(object sender, EventArgs e)
        {

            if (num1 == 0 && textBox1.TextLength > 0)
            {
                num1 = 0; textBox1.Clear();
            }
            else if (num1 > 0 && textBox1.TextLength > 0)
            {
                textBox1.Clear();
            }
        }

        private void btnback_Click(object sender, EventArgs e)
        {

            int lenght = textBox1.TextLength - 1;
            string text = textBox1.Text;
            textBox1.Clear();
            for (int i = 0; i < lenght; i++)
                textBox1.Text=textBox1.Text+text[i];


        }

        private void btnminus_Click(object sender, EventArgs e)
        {
            if (textBox1.Text != "")
            {
                num1 = float.Parse(textBox1.Text);
                textBox1.Clear();
                textBox1.Focus();
                zähler = 1;
            }
        }

        private void btnone_Click(object sender, EventArgs e)
        {
            textBox1.Text = textBox1.Text + 1;
        }

        private void bttntwo_Click(object sender, EventArgs e)
        {
            textBox1.Text = textBox1.Text + 2;
        }

        private void btnthree_Click(object sender, EventArgs e)
        {
            textBox1.Text = textBox1.Text + 3;
        }

        private void btnplus_Click(object sender, EventArgs e)
        {
            num1 = float.Parse(textBox1.Text);
            textBox1.Clear();
            textBox1.Focus();
            zähler = 2;
        }

        private void btnfour_Click(object sender, EventArgs e)
        {
            textBox1.Text = textBox1.Text + 4;
        }

        private void btnfive_Click(object sender, EventArgs e)
        {
            textBox1.Text = textBox1.Text + 5;
        }

        private void btnsix_Click(object sender, EventArgs e)
        {
            textBox1.Text = textBox1.Text + 6;
        }

        private void btnmultiply_Click(object sender, EventArgs e)
        {
            num1 = float.Parse(textBox1.Text);
            textBox1.Clear();
            textBox1.Focus();
            zähler = 3;
        }

        private void btnseven_Click(object sender, EventArgs e)
        {
            textBox1.Text = textBox1.Text + 7;
        }

        private void btneight_Click(object sender, EventArgs e)
        {
            textBox1.Text = textBox1.Text + 8;
        }

        private void btnnine_Click(object sender, EventArgs e)
        {
            textBox1.Text = textBox1.Text + 9;
        }

        private void btndivide_Click(object sender, EventArgs e)
        {
            num1 = float.Parse(textBox1.Text);
            textBox1.Clear();
            textBox1.Focus();
            zähler = 4;
        }

        private void btnzero_Click(object sender, EventArgs e)
        {
            textBox1.Text = textBox1.Text + 0;
        }

        private void btnequal_Click(object sender, EventArgs e)
        {
            
            rechner(zähler);
        }

        public void rechner(int count) 
        {

            //Liest welche Werte in der textBox1 Enthalten sind, diese Rechnung wird vereinfacht ausgelesen.

            switch (zähler)
            {
                case 1:
                    ans = num1 - float.Parse(textBox1.Text);
                    textBox1.Text = ans.ToString();
                    break;
                case 2:
                    ans = num1 + float.Parse(textBox1.Text);
                    textBox1.Text = ans.ToString();
                    break;
                case 3:
                    ans = num1 * float.Parse(textBox1.Text);
                    textBox1.Text = ans.ToString();
                    break;
                case 4:
                    ans = num1 / float.Parse(textBox1.Text);
                    textBox1.Text = ans.ToString();
                    break;
                default:
                    break;
            }
        }

        private void fehlfuktionToolStripMenuItem_Click(object sender, EventArgs e)
        {
            MessageBox.Show("Nach jeder Rechnung die Auslesentaste [=] drücken, sonst kann mit der nächsten Zahl keine andere Rechnung durchgeführt werden.","Fehlfunktion"+ MessageBoxIcon.Warning);
        }

        private void überToolStripMenuItem_Click(object sender, EventArgs e)
        {
            MessageBox.Show("© 2016 Benedict Benge\nProgrammierter Taschenrechner in Windows Forms C#");
        }

    }
}

3.003 Beiträge seit 2006
vor 7 Jahren

Ruf deine rechner-Methode im Click-Ereignis der Operatoren auf.

Allerdings ist das ganze code-behind-Gewusel wirklich sehr, sehr unschön.

LaTino

"Furlow, is it always about money?"
"Is there anything else? I mean, how much sex can you have?"
"Don't know. I haven't maxed out yet."
(Furlow & Crichton, Farscape)

5.658 Beiträge seit 2006
vor 7 Jahren

Allerdings ist das ganze code-behind-Gewusel wirklich sehr, sehr unschön.

Siehe dazu z.B. [Artikel] Drei-Schichten-Architektur

Weeks of programming can save you hours of planning

A
Asonger Themenstarter:in
10 Beiträge seit 2014
vor 7 Jahren

Allerdings ist das ganze code-behind-Gewusel wirklich sehr, sehr unschön.

Ich bin ein blutender Anfänger, damit befasse ich mich definitiv noch einmal genauer. 😃

Ruf deine rechner-Methode im Click-Ereignis der Operatoren auf.

Mir wurde der Tipp gegeben ich sollte doch eine Abfrage in die Cases Packen, in wie fern ist das gemeint und wie sollte das funktionieren ?
Bzw, was für eine Abfrage soll später dort stehen ?

5.658 Beiträge seit 2006
vor 7 Jahren

Das kann dir derjenige beantworten, der dir den Tip gegeben hat 😃
Ansonsten findest du hier im Forum mehrere Taschenrechner-Projekte und Parser für mathematische Formeln. Da kannst du dir anschauen, wie es umgesetzt wurde. Es gibt da aber (wie meistens) nicht DIE eine, richtige Herangehensweise.

Weeks of programming can save you hours of planning

A
Asonger Themenstarter:in
10 Beiträge seit 2014
vor 7 Jahren

Ansonsten findest du hier im Forum mehrere Taschenrechner-Projekte und Parser für mathematische Formeln.

Ich werde mich da mal umsehen, da ich relativ neu bin, könntest du mir das Verzeichnis verlinken ?
Gruß, Ben.

709 Beiträge seit 2008
vor 7 Jahren
3.003 Beiträge seit 2006
vor 7 Jahren

"Taschenrechner" oben in die Suche eingeben 😉.

Wenn der Tippgeber mit der Abfrage in der switch-Anweisung das meinte, was ich denke, was er meinte, dann...tu's nicht.

LaTino

"Furlow, is it always about money?"
"Is there anything else? I mean, how much sex can you have?"
"Don't know. I haven't maxed out yet."
(Furlow & Crichton, Farscape)

A
Asonger Themenstarter:in
10 Beiträge seit 2014
vor 7 Jahren

Wenn der Tippgeber mit der Abfrage in der switch-Anweisung das meinte, was ich denke, was er meinte, dann...tu's nicht.

Hättest du einen anderen Vorschlag für mich, diese Person hatte es ziemlich eilig, weshalb ich nichts mehr fragen konnte.

Grüße, Ben.

3.003 Beiträge seit 2006
vor 7 Jahren

Hab ich doch schon.

Ruf deine rechner-Methode im Click-Ereignis der Operatoren auf.

Langfassung: behandle die Buttons mit den Operatoren (plus,minus...) so, als seien sie das Gleichheitszeichen, zusätzlich zu dem, was sie sowieso schon tun.

LaTino

"Furlow, is it always about money?"
"Is there anything else? I mean, how much sex can you have?"
"Don't know. I haven't maxed out yet."
(Furlow & Crichton, Farscape)

771 Beiträge seit 2009
vor 7 Jahren

Das wird direkt auch nicht funktionieren, da z.B. bei "3 +" ja noch nicht die 2. Zahl bekannt ist.
Hier müsste man dann die Umgekehrte polnische Notation (UPN) verwenden, also "3 4 +".

Sonst hilft nur, sich die Operation getrennt zu merken und bei der nächsten Operation bzw. = diese erst auszuführen, also bei "3 + 4 - 5", bei + diese (sowie die eingegeben Zahl also 3) sich merken und bei - dann die gemerkte Operation "3 + 4" ausführen und sich dann die - wieder zu merken etc.

2.298 Beiträge seit 2010
vor 7 Jahren

Das wird direkt auch nicht funktionieren, da z.B. bei "3 +" ja noch nicht die 2. Zahl bekannt ist.
Hier müsste man dann die
>
verwenden, also "3 4 +".

Nö, da muss man halt nur aufpassen?

-> Eingabe erste Zahl
-> Eingabe Plus
    -> Bereits eine Berechnung vorhanden? 
           ->Rechne zusammen.
-> Eingabe zweite Zahl
-> Eingabe Mal
    -> Bereits eine Berechnung vorhanden?
           -> Rechne zusammen.
-> Eingabe dritte Zahl

Wissen ist nicht alles. Man muss es auch anwenden können.

PS Fritz!Box API - TR-064 Schnittstelle | PS EventLogManager |

H
523 Beiträge seit 2008
vor 7 Jahren

Vor ewigen Zeiten habe ich das in einem Taschenrechner mal mit dem ScriptControl von Microsoft gelöst, welches die Berechnung der eingegebenen Daten übernommen hat:


ScriptControl sc = new ScriptControl();
sc.Language = "VBScript";
txtErgebnis.Text = sc.Eval("5 * 5 + 10 + 3");

3.003 Beiträge seit 2006
vor 7 Jahren

Das wird direkt auch nicht funktionieren, da z.B. bei "3 +" ja noch nicht die 2. Zahl bekannt ist.


//Pseudocode
ergebnis = 0;
operand = neue_usereingabe;
wenn(buttonplus_geklickt)
    ergebnis += operand

Er hat nur eine Eingabebox, wenn ich mich nicht sehr täusche. Das aktuelle Ergebnis hält er vor - und dann geht das so 😃.

LaTino

"Furlow, is it always about money?"
"Is there anything else? I mean, how much sex can you have?"
"Don't know. I haven't maxed out yet."
(Furlow & Crichton, Farscape)

A
Asonger Themenstarter:in
10 Beiträge seit 2014
vor 7 Jahren

Mit folgenden Quellcode kam ich jetzt zu meinem gewünschten Ergebnis!

Danke an alle die ihre Tipps abgegeben haben. 😃

Er rechnet nun folgendes aus : 50+50-20 = 80
Vorher rechnete er : 50+50-20 = 30

Zwischenspeicher wurde ganz einfach eingerichtet.
Wie, wird in den Kommentarzeilen Erklärt. 😃

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

namespace Taschenrechner_2
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        /**
         * Textbox zwischenspeicher
         * */
        float operant1;
        /**
         * 0 = nicht definiert.
         * 1 = Plus
         * 2 = Minus
         * 3 = Mal
         * 4 = Geteilt
         */
        int rechenart;

        /**
         * Prozedur Zahl des Buttons wird in Textbox eingetragen
         */
        private void btnNull_Click(object sender, EventArgs e)
        {
            textBox.Text = textBox.Text + btnNull.Text;
        }
        private void btnEins_Click(object sender, EventArgs e)
        {
            textBox.Text = textBox.Text + btnEins.Text;
        }
        private void btnZwei_Click(object sender, EventArgs e)
        {
            textBox.Text = textBox.Text + btnZwei.Text;
        }
        private void btnDrei_Click(object sender, EventArgs e)
        {
            textBox.Text = textBox.Text + btnDrei.Text;
        }
        private void btnVier_Click(object sender, EventArgs e)
        {
            textBox.Text = textBox.Text + btnVier.Text;
        }
        private void btnFünf_Click(object sender, EventArgs e)
        {
            textBox.Text = textBox.Text + btnFünf.Text;
        }
        private void btnSechs_Click(object sender, EventArgs e)
        {
            textBox.Text = textBox.Text + btnSechs.Text;
        }
        private void btnSieben_Click(object sender, EventArgs e)
        {
            textBox.Text = textBox.Text + btnSieben.Text;
        }
        private void btnAcht_Click(object sender, EventArgs e)
        {
            textBox.Text = textBox.Text + btnAcht.Text;
        }
        private void btnNeun_Click(object sender, EventArgs e)
        {
            textBox.Text = textBox.Text + btnNeun.Text;
        }
        
        /*
         * Rechnet die vorherige Rechenoperation zusammen und speichert diese in Textbox, 
         * rechenart wird zurückgesetzt, da "=" keine Rechenart ist.
         * */
        private void btnGleich_Click(object sender, EventArgs e)
        {
            berechne();
            textBox.Text = operant1.ToString();
            rechenart = 0;
        }
        
        /* Rechenart zurückgesetzt, da "Reset" keine Rechnart ist, anschließend wird die Textbox gecleart
         */
        private void btnReset_Click(object sender, EventArgs e)
        {
            rechenart = 0;
            textBox.Clear();
        }
       
        /*Entfernt das letzte Zeichen in der Textbox
         */
        private void btnBack_Click(object sender, EventArgs e)
        {
            int lenght = textBox.TextLength - 1;
            string text = textBox.Text;
            textBox.Clear();
            for (int i = 0; i < lenght; i++)
                textBox.Text = textBox.Text + text[i];
        }

        /*Falls es keine Rechart angegeben ist, wird der momentan eingegebene Text in der Textbox zwischengespeichert, 
         * anschließend wird die Textbox gereinigt. Falls die Rechenart einem +, -, * oder geteilt entspricht, wird 
         * der zwischenspeicher mit dem zuletzt eingegebenen Wert in der Textbox mit dem jeweiligen letzten Rechenart berechnet.
         */
        private void btnPlus_Click(object sender, EventArgs e)
        {
            if(rechenart == 0)
            {
                operant1 = float.Parse(textBox.Text);
                textBox.Clear();
            }
            else
            {
                berechne();
            }
            rechenart = 1;
        }

        private void btnMinus_Click(object sender, EventArgs e)
        {
            if (rechenart == 0)
            {
                operant1 = float.Parse(textBox.Text);
                textBox.Clear();
            }
            else
            {
                berechne();
            }
            rechenart = 2;
        }

        private void btnMal_Click(object sender, EventArgs e)
        {
            if (rechenart == 0)
            {
                operant1 = float.Parse(textBox.Text);
               textBox.Clear();
            }
            else
            {
                berechne();
            }
            rechenart = 3;
        }

        private void btnGeteilt_Click(object sender, EventArgs e)
        {
            if (rechenart == 0)
            {
                operant1 = float.Parse(textBox.Text);
             textBox.Clear();
            }
            else
            {
                berechne();
            }
            rechenart = 4;
        }
        /*
         * Ruft für die jeweilige Rechenart die entsprechende Berechnungsfunktion auf,
         * schreibt das Ergebnis in den Zwischenspeicher Operant 1 und leert die Textbox.
         */
        private void berechne()
        {
            switch(rechenart)
            {
                case 0:
                    break;
                case 1:
                    operant1 = AddiereZweiZahlen(operant1, float.Parse(textBox.Text));
                    break;
                case 2:
                    operant1 = SubstrahiereZweiZahlen(operant1, float.Parse(textBox.Text));
                    break;
                case 3:
                    operant1 = MultipliziereZweiZahlen(operant1, float.Parse(textBox.Text));
                    break;
                case 4:
                    operant1 = DividiereZweiZahlen(operant1, float.Parse(textBox.Text));
                    break;
            }
            textBox.Clear();

        }

        private float AddiereZweiZahlen(float zahl1, float zahl2)
        {
            float ergebnis = zahl1 + zahl2;
            return ergebnis;
        }

        private float SubstrahiereZweiZahlen(float zahl1, float zahl2)
        {
            float ergebnis = zahl1 - zahl2;
            return ergebnis;
        }

        private float DividiereZweiZahlen(float zahl1, float zahl2)
        {
            float ergebnis = zahl1 / zahl2;
            return ergebnis;
        }

        private float MultipliziereZweiZahlen(float zahl1, float zahl2)
        {
            float ergebnis = zahl1 * zahl2;
            return ergebnis;
        }
    }
}
463 Beiträge seit 2009
vor 7 Jahren

Und wenn du nun noch statt


 /**
 * 0 = nicht definiert.
 * 1 = Plus
 * 2 = Minus
 * 3 = Mal
 * 4 = Geteilt
 */
 int rechenart;

folgendes schreibst:


public enum Rechenart
{

      Unknown,
       
       Plus,
       Minus,
       Mal,
       Geteilt

}

kannst du per Rechenart.Plus usw. prüfen und musst dir nciht immer die Werte merken... Eine Fehlerquelle weniger...

 private void berechne()
        {
            switch(rechenart)
            {
                case Rechenart.Unknown:
                    break;
                case Rechenart.Plus:
                    operant1 = AddiereZweiZahlen(operant1, float.Parse(textBox.Text));
                    break;
                case Rechenart.Minus:
                    operant1 = SubstrahiereZweiZahlen(operant1, float.Parse(textBox.Text));
                    break;
                case Rechenart.Mal:
                    operant1 = MultipliziereZweiZahlen(operant1, float.Parse(textBox.Text));
                    break;
                case Rechenart.Geteilt:
                    operant1 = DividiereZweiZahlen(operant1, float.Parse(textBox.Text));
                    break;
            }
            textBox.Clear();

        }

4.942 Beiträge seit 2008
vor 7 Jahren

Und noch ein Tipp:
du kannst die Button-Click-Methoden der Ziffern auf eine reduzieren:


private void btnZiffer_Click(object sender, EventArgs e)
{
    Button btn = sender as Button;
    if (btn != null)
    {
        textBox.Text += btn.Text;
    }
}

(s.a. [FAQ] Casten aber richtig: () / is / as)

Du mußt dann nur im Designer (Eigenschaftenfenster) die Click-Methode für die 10 Ziffern-Buttons auf diese Methode setzen.

PS: Und auch bei den Operationen könntest du den identischen Code in eine eigene Methode auslagern und dann diese aufrufen.

3.003 Beiträge seit 2006
vor 7 Jahren

Und noch ein Tipp: du solltest als Programmierer eine gewisse Faulheit entwickeln. Damit meine ich, dass es dich wirklich stören sollte, sobald du mehrmals nahezu identischen Code tippen musst.

Der Tipp von Th69 schlägt zum Beispiel in diese Kerbe - statt zehnmal denselben Code immer und immer wieder zu schreiben, macht man das nur einmal. Der von dir gepostete Abschnitt hat noch einige weitere Ecken, wo du ohne Not immer wieder dasselbe machst.


        private float AddiereZweiZahlen(float zahl1, float zahl2)
        {
            float ergebnis = zahl1 + zahl2;
            return ergebnis;
        }

        private float SubstrahiereZweiZahlen(float zahl1, float zahl2)
        {
            float ergebnis = zahl1 - zahl2;
            return ergebnis;
        }

        private float DividiereZweiZahlen(float zahl1, float zahl2)
        {
            float ergebnis = zahl1 / zahl2;
            return ergebnis;
        }

        private float MultipliziereZweiZahlen(float zahl1, float zahl2)
        {
            float ergebnis = zahl1 * zahl2;
            return ergebnis;
        }

Dieser Abschnitt ist zum Beispiel komplett überflüssig: du machst eine simple Rechenoperation und lieferst das Ergebnis zurück. Rechenoperationen darf man ruhig direkt aufrufen:


float Berechne()
{
    float operand2 = float.Parse(textBox.Text);
    textBox.Clear();

    switch (rechenart)
    {
        case 1: return operand1 + operand2;
        case 2: return operand1 - operand2;
        case 3: return operand1 * operand2;
        case 4: return operand1 / operand2;
        default: return operand1;
    }
}
//anstelle von berechne() dann:
operand1 = Berechne();

Zusammen mit dem enum von stefan.haegele hast du dann sehr viel besser lesbaren Code. Kürzer ist er auch noch, und damit weniger fehleranfällig.

LaTino

"Furlow, is it always about money?"
"Is there anything else? I mean, how much sex can you have?"
"Don't know. I haven't maxed out yet."
(Furlow & Crichton, Farscape)