Probleme Taschenrechner



  • Hallo an alle.
    Ich bin absoluter Neuling im Fach Programmieren. Und bin noch nicht weiter als Kontrollstrukturen...will das richtig verstehen bevor ich weitermache.

    Ich möchte einen "typischen" Taschenrechner schreiben.

    Nun das was nicht klappt:

    1. In der switch Anweisung ist das Problem das wenn ich mit 0 beenden will, das Programm trotzdem noch einmal z1 und z2 abfragt. Und wenn ich jetzt z.B. einen Buchstaben schreibe bricht das Programm ab, läuft aber noch einmal die cout's ab... 🙂

    Was übersehe ich da? Oder fehlt etwas?

    Bin für jeden Tip dankbar...
    Her mit der Kritik....

    #include <iostream>
    
    using namespace std;
    
    int main()
    {
        float z1;
        float z2;
        int op;
        char wahl;
    
        do{
            cout << "Das ist ein Taschenrechner." << endl;
            cout << "Wählen Sie aus: " << endl;
            cout << "Addition [1]." << endl;
            cout << "Subtraktion [2]." << endl;
            cout << "Multiplikation [3]." << endl;
            cout << "Division [4]." << endl;
            cout << "Beenden [0]." << endl;             //Wenn ich mit 0 beenden will muss ich trotzdem noch z1 und z2 eingeben
            cin >> op;
            cout << "Bitte Zahl-1 eingeben: " << endl;
            cin >> z1;
            cout << "Bitte Zahl-2 eingeben: " << endl;
            cin >> z2;
    
            switch(op){
            case 1 :
                cout << "Das Ergebnis ist: " << z1 + z2 << endl << endl;
                break;
            case 2 :
                cout << "Das Ergebnis ist: " << z1 - z2 << endl << endl;
                break;
            case 3 :
                cout << "Das Ergebnis ist: " << z1 * z2 << endl << endl;
                break;
            case 4 :
                cout << "Das Ergebnis ist: " << z1 / z2 << endl << endl;
                break;
            case 0 :
                cout << "Beendet." << endl;
                break;
            default :                                   //Funktioniert nicht - beendet das Programm
                cout << "Falsche Eingabe!";
    
            } cout << "Möchten Sie weiter rechnen? j/n" << endl;
              cin >> wahl;
    
        } while(wahl == 'j');
                cout << "Bis zum nächsten Mal." << endl;
                system("pause");
    
    }
    


  • Wie lange läuft denn deine Schleife?


  • Mod

    Zu der Frage mit der 0: Nun, ist doch klar, wenn du den Verlauf des Codes folgst. Wenn du nicht möchtest, dass das passiert, musst du halt den logischen Verlauf des Programms ändern. Eine Möglichkeit wäre, sich nicht darauf zu versteifen, alles mit einem switch zu machen. Du darfst ja auch gerne direkt nach der Frage testen, ob diese eine bestimmt Antwort hatte und entsprechend reagieren.

    Zu der Frage mit den Buchstaben: Das ist leider ein bisschen kompliziert. Prinzipiell kannst du von jeder Eingabeaufforderung testen, ob sie erfolgreich war, zum Beispiel so

    int i;
    if (cin >> i)
    {
      // i erfolgreich gelesen
    }
    else
    {
      // Lesefehler, z.B. Buchstabe oder Dateiende
    }
    

    Und dann musst du dir halt ausdenken, was du im Fehlerfall sinnvoll tun willst.
    Das Problem hier ist, dass du bei dir im Programm viele Einzelabfragen hast, und diese alle mit solchen Abfragen zu versehen wäre unverhältnismäßig für die schwere des Problems, und würde den Programmverlauf schwer nachvollziehbar machen. In "richtigen" Programmen würde man dies verlagern, indem man sich passende Funktionen schreibt, die das erledigen, aber das geht wahrscheinlich über deinen jetzigen Wissensstand hinaus. Außer, dass man das meist auch gar nicht selber machen würde, sondern fertige Frameworks dafür nutzen würde, da Ein- und Ausgabe ein sehr übliches Problem ist, das schon vielfach besser gelöst wurde, als man das mal eben schnell selber hinbekommen würde.
    Kurz gesagt: Eine konsequente Fehlerbehandlung für Buchstaben ginge prinzipiell, aber ist viel Aufwand, und bringt dir letztlich nicht viel nützliches bei.



  •       cin >> op;
          cout << "Bitte Zahl-1 eingeben: " << endl;
          cin >> z1;
          cout << "Bitte Zahl-2 eingeben: " << endl;
          cin >> z2;
    

    cin ist für die Eingabeaufforderung zuständig.
    Demnach fragst Du direkt nach dem op noch nach z1 und z2, genau wie Du es beschrieben hast. Den Verbesserungsvorschlag findest Du bei SeppJs Antwort.



  • @Schlangenmensch Das habe ich als noch nicht so wichtig empfunden. Ist das Prinzipiell?



  • @SeppJ Vielen Dank. Ich hatte es schon tatsächlich mit if versucht aber da kamen noch mehr Probleme bei raus...weil ich das - wie du schon geschrieben hast - zu kompliziert gemacht hatte... 🙂
    Werde das heute Abend in Angriff nehmen...

    Alles Gute
    Alex......



  • @c52jrear Naja, du wunderst dich doch, dass die Schleife weiter ausgeführt wird, wenn du eine 0 eingibst. Also, für dein Problem ist das schon prinzipiell.



  • @Schlangenmensch Danke. Das werde ich berücksichtigen!!!



  • Bin doch früher dazu gekommen...
    Also ich habe das jetzt so "gelöst". Das mit den Buchstaben werde ich mich wohl noch abfinden müssen...hehe

    Und bezüglich wie oft die Schleife wiederholt wird, verstehe ich nicht bis zum Ende wie ich das realisieren soll. Ich hatte das mit 'for' versucht - ist aber nichts bei rumgekommen!? Ist der Ansatz dazu richtig?
    Daaanke....

    #include <iostream>
    
    using namespace std;
    
    int main()
    {
        float z1;
        float z2;
        int op;
        char wahl;
    
        cout << "Das ist ein Taschenrechner." << endl;
    
        do{
        cout << "Wählen Sie eine Option: " << endl;
        cout << "Addition [1]." << endl;
        cout << "Subtraktion [2]." << endl;
        cout << "Multiplikation [3]." << endl;
        cout << "Division [4]." << endl;
        cout << "Beenden? [0]" << endl;
        cin >> op;
            if(op == 0){
                cout << "Beendet, bis zum nächsten Mal." << endl;
            } else {
                if(op == 1){
                    cout << "Bitte geben Sie die erste Zahl ein: " << endl;
                    cin >> z1;
                    cout << "Bitte geben Sie die zweite Zahl ein: " << endl;
                    cin >> z2;
                    cout << "Das Ergebnis ist: " << z1 + z2 << endl << endl;
                } else {
                    if(op == 2){
                        cout << "Bitte geben Sie die erste Zahl ein: " << endl;
                        cin >> z1;
                        cout << "Bitte geben Sie die zweite Zahl ein: " << endl;
                        cin >> z2;
                        cout << "Das Ergebnis ist: " << z1 - z2 << endl << endl;
                    } else {
                        if(op == 3){
                            cout << "Bitte geben Sie die erste Zahl ein: " << endl;
                            cin >> z1;
                            cout << "Bitte geben Sie die zweite Zahl ein: " << endl;
                            cin >> z2;
                            cout << "Das Ergebnis ist: " << z1 * z2 << endl << endl;
                        } else {
                            if(op == 4){
                                cout << "Bitte geben Sie die erste Zahl ein: " << endl;
                                cin >> z1;
                                cout << "Bitte geben Sie die zweite Zahl ein: " << endl;
                                cin >> z2;
                                cout << "Das Ergebnis ist: " << z1 / z2 << endl << endl;
                            }
                        }
                    }
                }
            }
        } while(op != 0);
    }
    

  • Mod

    Macht es denn, was du willst?

    Was ich eigentlich nicht erreichen wollte war, dass du solch eine if-Kaskade schreibst. Dein Programm darf mehr als nur eine einzelne Logikanweisung zur Flusskontrolle enthalten! Meine Vorstellung ging eher in Richtung

    do
    {
      cin >> op;
      if (op == 0) break;
      switch(op)
         // ...
    } while(1)
    


  • @SeppJ Ja daran habe ich schon gedacht... 🙂
    Angenehmes Wochenende....



  • Viel einfacher ist wahrscheinlich folgendes:

    void rechner() {
        std::cout << "Bitte geben Sie eine Aufgabe ein oder Beenden mit einem Buchstaben oder Dateiende-Zeichen!\n";
        double z1, z2, ergebnis;
        char op;
        while (std::cin >> z1 >> op >> z2) {
            switch (op) {
                case '+': ergebnis = z1 + z2; break;
                case '-': ergebnis = z1 - z2; break;
                default:
                    std::cout << "Unbekannter Operator: " << op << '\n';
                    continue;
            }
            std::cout << "Ergebnis: " << ergebnis << "\n";
        }
    }
    

    Hier ist der Trick, dass du gleich Zahl + Operator + Zahl einliest und das Einlesen dieser 3 Dinge auf Richtigkeit prüfst.



  • @wob Habe das jetzt so "gelöst"...
    Ich versuche das halt alles "ausführlicher" zu machen damit ich mich direkt länger damit beschäftige...hehe

    Alles Gute...

    #include <iostream>
    
    using namespace std;
    
    int main()
    {
        float z1;
        float z2;
        int op;
        char wahl;
    
        do{
            cout << "Das ist ein Taschenrechner." << endl;
            cout << "Wählen Sie aus: " << endl;
            cout << "Addition [1]." << endl;
            cout << "Subtraktion [2]." << endl;
            cout << "Multiplikation [3]." << endl;
            cout << "Division [4]." << endl;
            cout << "Beenden [0]." << endl;             //Wenn ich mit 0 beenden will muss ich trotzdem noch z1 und z2 eingeben
            cin >> op;
    
            if(op == 0){
                cout << "Beendet.\n";
            } else {
    
                cout << "Bitte Zahl-1 eingeben: " << endl;
                cin >> z1;
                cout << "Bitte Zahl-2 eingeben: " << endl;
                cin >> z2;
    
                switch(op){
                case 1 :
                    cout << "Das Ergebnis ist: " << z1 + z2 << endl << endl;
                    break;
                case 2 :
                    cout << "Das Ergebnis ist: " << z1 - z2 << endl << endl;
                    break;
                case 3 :
                    cout << "Das Ergebnis ist: " << z1 * z2 << endl << endl;
                    break;
                case 4 :
                    cout << "Das Ergebnis ist: " << z1 / z2 << endl << endl;
                    break;
                case 0 :
                    cout << "Beendet." << endl;
                    break;
                //default :                                   //Funktioniert nicht - beendet das Programm
                //    cout << "Falsche Eingabe!";
    
                } cout << "Möchten Sie weiter rechnen? j/n" << endl;
                  cin >> wahl;
                  cout << endl;
            }
    
        } while(wahl == 'j');
                cout << "Bis zum nächsten Mal." << endl;
                system("pause");
    }
    

  • Gesperrt

    Nicht ganz im Sinne von Dijkstra, aber was soll's:

    #include <iostream>
    
    using namespace std;
    
    int main()
    {
        float z1;
        float z2;
        int op;
        char wahl;
    
        while (1)
        {
            cout << "Das ist ein Taschenrechner." << endl;
            cout << "Wählen Sie aus: " << endl;
            cout << "Addition [1]." << endl;
            cout << "Subtraktion [2]." << endl;
            cout << "Multiplikation [3]." << endl;
            cout << "Division [4]." << endl;
            cout << "Beenden [0]." << endl;
            cin >> op;
            if (op != 0)
            {
                cout << "Bitte Zahl-1 eingeben: " << endl;
                cin >> z1;
                cout << "Bitte Zahl-2 eingeben: " << endl;
                cin >> z2;
            }
            switch (op)
            {
            case 1:
                cout << "Das Ergebnis ist: " << z1 + z2 << endl
                     << endl;
                break;
            case 2:
                cout << "Das Ergebnis ist: " << z1 - z2 << endl
                     << endl;
                break;
            case 3:
                cout << "Das Ergebnis ist: " << z1 * z2 << endl
                     << endl;
                break;
            case 4:
                cout << "Das Ergebnis ist: " << z1 / z2 << endl
                     << endl;
                break;
            case 0:
                cout << "Beendet." << endl;
                goto endloop;
            default:
                cout << "Falsche Eingabe!" << endl;
            }
            cout << "Möchten Sie weiter rechnen? j/n" << endl;
            cin >> wahl;
            if (wahl != 'j')
            {
                break; // auch: "goto endloop;" möglich...
            }
        }
    endloop:
        cout << "Bis zum nächsten Mal." << endl;
        cout << "press any key to close..." << endl;
        cin >> wahl;
        return EXIT_SUCCESS;
    }
    


  • @EinNutzer0 Danke für diesen Tipp: 'goto' kannte ich noch nicht....



  • @c52jrear sagte in Probleme Taschenrechner:

    @EinNutzer0 Danke für diesen Tipp: 'goto' kannte ich noch nicht....

    Das war kein ernst gemeinter Tipp! Vergiss goto schnellstmöglich wieder!

    (Deswegen auch "Nicht ganz im Sinne von Dijkstra" - siehe https://homepages.cwi.nl/~storm/teaching/reader/Dijkstra68.pdf)



  • @wob 😃 ... und wieder was dazu gelernt...!


Anmelden zum Antworten