Try Catch Ausnahmebehandlung
-
Hallo zusammen,
ich sitze gerade an eine Aufgabe, bei der ich per try catch Funktion die Eingaben in einem Taschenrechner abfangen soll.
Es sollen keine Buchstaben eingegeben werden und die Division durch 0 soll ebenfalls nicht möglich sein bzw. soll der Benutzer darauf hingewiesen werden.
Allerdings kommt bei meinem Code immer nur die Meldung mit den Buchstaben.
Habe ich etwas bei der Konvertierung der Werte falsch gemacht ?Bitte helft mir auf die Sprünge
#include "taschenrechner.h" #include "ui_taschenrechner.h" Taschenrechner::Taschenrechner(QWidget *parent) : QMainWindow(parent) , ui(new Ui::Taschenrechner) { ui->setupUi(this); } Taschenrechner::~Taschenrechner() { delete ui; } //der Aufzählungstyp enum fehler {keineZahl, istNull}; //die Funktion zur Prüfung void Taschenrechner::check(float zahl1,float zahl2) { zahl1 = locale().toFloat(ui->lineEdit->text()); if (ui->radioButtonDivision->isChecked() == true) if (zahl1 == 0) { throw istNull; ui->lineEdit->setFocus(); } if (!isdigit(zahl1)) { throw keineZahl; ui->lineEdit->setFocus(); } zahl2 = locale().toFloat(ui->lineEdit_2->text()); if (ui->radioButtonDivision->isChecked() == true) if (zahl2 == 0) { throw istNull; ui->lineEdit_2->setFocus(); } if (!isdigit(zahl2)) { throw keineZahl; ui->lineEdit_2->setFocus(); } } //der Slot für die Schaltfläche float Taschenrechner::berechnen(float zahl1, float zahl2) { float ergebnis = 0; //welche Rechenoperation ist ausgewählt? //die Addition if (ui->radioButtonAddition->isChecked() == true) ergebnis = zahl1 + zahl2; //die Subtraktion if (ui->radioButtonSubtraktion->isChecked() == true) ergebnis = zahl1 - zahl2; //die Division if (ui->radioButtonDivision->isChecked() == true) ergebnis = zahl1 / zahl2; //die Multiplikation if (ui->radioButtonMultiplikation->isChecked() == true) ergebnis = zahl1 * zahl2; return (ergebnis); } void Taschenrechner::Ausnahmebehandlung() { float zahl1, zahl2; bool Ausnahme = false; QString ausgabe; zahl1 = locale().toFloat(ui->lineEdit->text()); zahl2 = locale().toFloat(ui->lineEdit_2->text()); try { check(zahl1, zahl2); } catch (fehler e) { switch (e) { case istNull: QMessageBox::warning(this,"Fehler","Eine Division durch 0 ist nicht moeglich."); Ausnahme = true; break; case keineZahl: QMessageBox::warning(this,"Fehler","Buchstaben sind nicht erlaubt, bitte eine Zahl eingeben."); Ausnahme = true; break; } } if (Ausnahme == false) { //die Ausgabe setzen ausgabe = locale().toString(berechnen(zahl1, zahl2)); //das Ergebnis anzeigen ui->labelErgebnis->setText(ausgabe); //und auch in der LCD-Anzeige ui->lcdNumberErgebnis->display(ausgabe); } } void Taschenrechner::on_pushButton_clicked() { Ausnahmebehandlung(); }
-
Hallo,
bisschen aufräumen wäre gut (zahl1 kommt aus lineEdit, wird übergeben und wieder eingelesen? Was soll das?).
Für die auf die Sprünge helfen: toFloat hat einen zweiten Parameter, mit dem du checken kannst, ob sich der übergebene String in eine Zahl konvertieren lässt. Nutze diesen Parameter. Ich weiss gar nicht, wie du dir das mit isdigit(float) vorgestellt hast. Wenn es mit dem zweiten Parameter nicht klappt: debugger! (oder am besten sofort, damit dir klar wird, was da nicht funktioniert).
-
@SGEKevin sagte in Try Catch Ausnahmebehandlung:
if (ui->radioButtonDivision->isChecked() == true)
Was ist der Returntyp von
isChecked
? Wenn der Typbool
ist, kannst du das so schreiben. Ansonsten würde ich empfehlen statt dessen einfach nurif (ui->radioButtonDivision->isChecked())
zu schreiben.if (zahl1 == 0) { throw istNull; ui->lineEdit->setFocus(); }
throw
wirft eine exception, d.h. es wird sofort(*) zum passendencatch
Block gesprungen. Dasui->lineEdit->setFocus();
dahinter wird nicht mehr ausgeführt.*: OK, vor dem ausführen des passenden
catch
Block wird noch Stack-Unwinding gemacht, aber darum geht's hier nicht.
-
Danke erstmal für die Antworten
Ich habe den Code mal etwas überarbeitet und schlanker gestaltet.
Allerdings ist mir immer noch nicht klar wie ich zwischen Buchstaben und 0 unterscheiden soll. Sobald der Radio-Button Division angeklickt ist, wird immer der Fehler angezeigt, dass nicht durch 0 geteilt werden darf obwohl ich auch Buchstaben eingebe.
Was kann ich hier noch ändern ?#include "taschenrechner.h" #include "ui_taschenrechner.h" Taschenrechner::Taschenrechner(QWidget *parent) : QMainWindow(parent) , ui(new Ui::Taschenrechner) { ui->setupUi(this); } Taschenrechner::~Taschenrechner() { delete ui; } //der Aufzählungstyp enum fehler {keineZahl, istNull}; //die Funktion zur Prüfung void Taschenrechner::checked(float zahl1, float zahl2) { bool ok; zahl1 = ui->lineEdit->text().toFloat(&ok); if (ui->radioButtonDivision->isChecked() == true) if (zahl1 == 0) { ui->lineEdit->setFocus(); throw istNull; } if (ok == false) { ui->lineEdit->setFocus(); throw keineZahl; } zahl2 = ui->lineEdit_2->text().toFloat(&ok); if (ui->radioButtonDivision->isChecked() == true) if (zahl2 == 0) { ui->lineEdit_2->setFocus(); throw istNull; } if (ok == false) { ui->lineEdit_2->setFocus(); throw keineZahl; } } //der Slot für die Schaltfläche void Taschenrechner::on_pushButton_clicked() { float zahl1, zahl2, ergebnis = 0; bool Ausnahme = false; QString ausgabe; zahl1 = locale().toFloat(ui->lineEdit->text()); zahl2 = locale().toFloat(ui->lineEdit_2->text()); //welche Rechenoperation ist ausgewählt? //die Addition if (ui->radioButtonAddition->isChecked() == true) ergebnis = zahl1 + zahl2; //die Subtraktion if (ui->radioButtonSubtraktion->isChecked() == true) ergebnis = zahl1 - zahl2; //die Division if (ui->radioButtonDivision->isChecked() == true) ergebnis = zahl1 / zahl2; //die Multiplikation if (ui->radioButtonMultiplikation->isChecked() == true) ergebnis = zahl1 * zahl2; try { checked(zahl1, zahl2); } catch (fehler e) { switch (e) { case istNull: QMessageBox::warning(this,"Fehler","Eine Division durch 0 ist nicht moeglich."); Ausnahme = true; break; case keineZahl: QMessageBox::warning(this,"Fehler","Buchstaben sind nicht erlaubt, bitte eine Zahl eingeben."); Ausnahme = true; break; } } if (Ausnahme == false) { //die Ausgabe setzen ausgabe = locale().toString(ergebnis); //das Ergebnis anzeigen ui->labelErgebnis->setText(ausgabe); //und auch in der LCD-Anzeige ui->lcdNumberErgebnis->display(ausgabe); } }
-
Du führst ja bisher auch zuerst immer die Rechenoperation aus und erst anschließend rufst du
checked
auf!Außerdem, wie @Jockelx schon geschrieben hast, übergibst du die beiden Zahlen als Parameter, verwendest sie aber gar nicht (sondern liest sie wieder aus den Editfeldern aus) - die Zeilen 24 und 38 sind also eigentlich überflüssig. Da du dort jedoch den Parameter
ok
übergibst und auswertest, solltest du stattdessen die Stringwerte als Parameter übergeben, alsovoid Taschenrechner::checked(QString zahl1, QString zahl2)
Und die Abfrage auf Buchstaben führst du in der falschen Reihenfolge durch (du überprüfst zuerst auf
istNull
).Und dann ist auch noch logisch falsch, daß du
zahl1
auf0
abfragst und als Fehler ansiehst (aber0 / zahl2
ist ja erlaubt).Edit: Ich finde jedoch die Aufgabe (als auch die Umsetzung) hier mit Exceptions zu arbeiten nicht gut, denn hier wird die Ausnahmebehandlung für die Umsetzung der Logik benutzt (und das ist ein Anti-Pattern!).
Hier würden auch normale Überprüfungsfunktionen (mitbool
als Rückgabewert) ausreichen.
-
@SGEKevin sagte in Try Catch Ausnahmebehandlung:
zahl1 = ui->lineEdit->text().toFloat(&ok); if (ui->radioButtonDivision->isChecked() == true) if (zahl1 == 0) ... if (ok == false) ...
Hier hast du ein Problem. Ob
toFloat
fehlgeschlagen ist, ist inok
gespeichert. Du testest das aber erst NACHDEM du deinen anderen Check, in welchem zu auchzahl1
überprüfst, machst. Aber welchen Wert hat dennzahl1
, wenn nicht konvertiert werden konnte? Du solltest direkt nach dem toFloat aufif (!ok)
testen.