Float Variable auf Zahlen / Buchstaben prüfen || Try...Catch Exceptions



  • Hallo!

    Ich habe einen einfachen Taschenrechner als Programm und versuche per Try...Catch-Block sicherzustellen, dass der Nutzer in die lineEdit Felder meines Formulars (der Taschenrechner) nur Zahlen eingibt. Wenn Buchstaben und Sonderzeichen eingegeben werden, soll der Block einen Fehler werfen.

    Ich habe bereits die Anweisung, einen Fehler zu werfen, wenn versucht wird, durch "0" zu teilen, aber ich weiß nicht, wie ich den eingegebenen Wert auf Buchstaben überprüfen kann. Ich habe im Internet nach Lösungen gesucht, aber keine hat für mich funktioniert. Für die lineEdit-Felder habe ich Pointer vereinbart.

    Mein Code bisher:

    void Taschenrechner::check_exceptions(float value) {
        float e = value;    
        try {
            // Überprüfen ob durch 0 geteilt wird
            if ((value == 0) && (ui->radioButtonDivision->isChecked())) {
                lineEditPointer_2->setFocus();
                throw 0;
            }
            // Überprüfen, ob ein Buchstabe eingegeben wurde (funktioniert so nicht)
            if (!isdigit(value)) {
                lineEditPointer->setFocus();
                throw "e";
            }
        } catch (int e) {
            QMessageBox::information(this, "Fehler!", "Durch Null teilen ist nicht möglich.\nBitte die Eingabe korrigieren.");
        } catch (const char *e) {
            QMessageBox::information(this, "Fehler!", "Es wurde keine Zahl eingegeben.\nBitte die Eingabe korrigieren.");
        } catch (...) {
            QMessageBox::information(this, "Fehler!", "Anderer Fehler...");
        }
    }
    

    In dem Block oben möchte ich, dass die Funktion prüft, ob ein Buchstabe eingegeben wurde, aber ich weiß leider nicht wie ... Die Funktion, die den Wert an "check_exception()" übergibt ist (kurz gefasst) folgende:

    void Taschenrechner::on_pushButton_clicked() {
        float zahl1, zahl2, ergebnis = 0;
        QString ausgabe;
    
        zahl1 = locale().toFloat(lineEditPointer->text());
        zahl2 = locale().toFloat(lineEditPointer_2->text());
    
    //diesen Part ändere ich später noch ab um die Konvertierung zu prüfen
        check_exceptions(zahl2); 
    
    // Hier wird die Rechenoperation geprüft und die Berechnung durchgeführt
    // "ergebnis" bekommt dann das Ergebnis der Rechnung zugewiesen
    
        ausgabe = locale().toString(ergebnis);
    
    // Ergebnis wird ausgegeben
    }
    

    Würde mich freuen, wenn ihr mir hierbei weiterhelfen könnt. Mein einziges Problem ist wirklich zu überprüfen, ob die Variable "float value", die in den oberen Code reingeht, nur Zahlen / andere Werte als Zahlen enthält.

    Vielen Dank im Voraus!



  • @Masch sagte in Float Variable auf Zahlen / Buchstaben prüfen || Try...Catch Exceptions:

        // Überprüfen, ob ein Buchstabe eingegeben wurde (funktioniert so nicht)
        if (!isdigit(value)) {
            lineEditPointer->setFocus();
            throw "e";
        }
    

    Warum konvertierst du nicht einfach zu std::stof? Wenn es kein float ist wird ne Exception geworfen.

    Und warum verschachtelst du nicht einfach deine Message Boxen?

    @Masch sagte in Float Variable auf Zahlen / Buchstaben prüfen || Try...Catch Exceptions:

    zahl1 = locale().toFloat(lineEditPointer->text());
    zahl2 = locale().toFloat(lineEditPointer_2->text());
    

    Oder warum benutzt du nicht den ok Parameter von toFloat(const QString &s, bool *ok = nullptr)? Die Funktion sagt dir doch Bescheid wenn was schief läuft.

    https://en.cppreference.com/w/cpp/string/basic_string/stof
    https://doc.qt.io/qt-5/qlocale.html#toFloat



  • @eigenartig Danke für die Rückmeldung! Ist eine gute Idee mit dem *ok Parameter. Ich hab jedoch leider eine Aufgabenstellung, die voraussetzt, dass ich eine eigene Funktion schreibe, in der per Try...Catch überprüft wird, ob die Konvertierung funktioniert hat. Heißt, ich muss also mit einer extra Funktion wenigstens arbeiten.

    Ich hatte auch versucht, eine Bool-Funktion zu schreiben und die als "ok"-Parameter in "toFloat" reinzugeben, das gibt jedoch einen Fehler zurück (mit einer bool variable würde es klappen).

    Danke auf jeden Fall schon mal für die Ideen, ich versuche ob ich "stof" irgendwie in der Funktion verwenden kann. Hierfür muss ich allerdings auch zuerst "float value" (was in die Funktion eingespeist wird) zu nem "string" umwandeln, oder?

    Vielen Dank!



  • @Masch sagte in Float Variable auf Zahlen / Buchstaben prüfen || Try...Catch Exceptions:

    Danke auf jeden Fall schon mal für die Ideen, ich versuche ob ich "stof" irgendwie in der Funktion verwenden kann. Hierfür muss ich allerdings auch zuerst "float value" (was in die Funktion eingespeist wird) zu nem "string" umwandeln, oder?

    Du hast doch in Qt schon sowas wie lineEditPointer->text().toStdString() damit bitte einfach stof füttern und try/catch-Block herum.

    https://doc.qt.io/qt-5/qstring.html#toStdString



  • @eigenartig Danke für deine Hilfe.

    Ich hab die "check_exceptions()" Funktion abgeändert, sodass sie nun bool fehler = true zurückgibt, wenn einer der Fehler im try-Block auftritt. Ich denke so funktioniert es sehr gut, vielen Dank dafür!

    Für mein Verständnis jedoch, kannst du mir erklären was ich für folgende Punkte machen muss (Try...Catch finde ich noch ein bisschen kompliziert)

    1. Wie kann ich speziell diesen Konvertierungsfehler abfangen per catch()? Hier wird grundsätzlich der Block für "catch(...)" aktiv
    2. Wie muss ich die Catch-Blöcke abändern, damit es nun auch auf Durch Null teilen reagiert?
    3. Was muss der try-Block idealerweise "throwen"?

    Für alle drei if-Bedingungen im Try-Block reagiert Catch(...). Wenn du mir helfen könntest, die Catch Blöcke entsprechend abzuändern, das wäre super 🙂 Vielen Dank schon mal soweit, der neue Code nochmal im Anschluss.

    bool Taschenrechner::check_exceptions() {
        bool fehler = false;
        try {
            // Durch Null teilen
            if ((lineEditPointer_2 == 0) && (ui->radioButtonDivision->isChecked())) {
                lineEditPointer_2->setFocus();
                throw 0;
                fehler = true;
            }
            // Konvertierung zu Float misslingt
            if (!stof(lineEditPointer->text().toStdString())) {
                lineEditPointer->setFocus();
                throw "e";
                fehler = true;
            }
            if (!stof(lineEditPointer_2->text().toStdString())) {
                lineEditPointer_2->setFocus();
                throw "e";
                fehler = true;
            }
        } catch (int e) {
            QMessageBox::information(this, "Fehler!", "Durch Null teilen ist nicht möglich.\nBitte die Eingabe korrigieren.");
        } catch (string e) {
            QMessageBox::information(this, "Fehler!", "Es wurde keine Zahl eingegeben.\nBitte die Eingabe korrigieren.");
        } catch (...) {
            QMessageBox::information(this, "Fehler!", "Anderer Fehler...");
        }
        return fehler;
    }
    


  • Versuchs mal hiermit

    bool isfloat(const std::string& s){
        try{
            std::stof(s);
        }
    
        catch(const std::exception& ){
            return false;
        }
    
        return true;
    }
    

    Dein Code ist jedoch voller Unsinn, du sollst nicht einfach so mit irgendwelchen Werten rumwerfen, sondern Objekte die von std::exception abgeleitet sind. Und du sollst in diesem Fall überhaupt nicht werfen.

    Wie gesagt, dein try/catch-Block hast du jetzt. Zu guter Letzt musst du nur noch die Message Boxen mit if verschachteln.


Anmelden zum Antworten