programm stürzt ab



  • Hallo,

    bei meinen Programm gibt der string eingabe() den Ort an wo sich die Datenbank befindet, z.B. localhost, stimmt der Ort jetzt nicht, z.B. durch einen Schreibfehler, stürzt das Programm nur noch ab ohne die Fehlermeldung zu bringen. Wie kann ich das ändern?

    datenbank::datenbank():mysql(NULL), ergebnis_(NULL), reihe_(NULL) {
        // Datenbank initialisieren
        mysql = mysql_init(NULL);
        // Verbindung mit Datenbank herrstellen
        mysql = mysql_real_connect(mysql, eingabe().c_str(), "root","******", "notizen", 0,NULL, 0);
        fehlerpruefen();
    }
    
    void datenbank::fehlerpruefen() {
        if (mysql_errno(mysql) !=0) {
        fltk::message("Fehler in der Datenbank! Programm wird beendet.");
        exit(0);
        }
    }
    


  • 3 magische worte

    throw
    try
    catch



  • wie kann ich das für mein Programm umsetzen



  • Hör nicht auf steff3. Du benutzt ja eine C API. Die kann ja gar keine C++ Exceptions schmeissen. 😉



  • Versuch es doch mal so:
    Über den Datenbankpointer kannst Du eventuelle Fehler abfangen.

    MYSQL *db;
    
    db = mysql_init(NULL);
      if(!db)
      {
      	printf("FEHLER! Kann Datenbank nicht initialisieren! \n");
    	return 1;
      }
    
    db = mysql_real_connect(db,HOST,USER,PASS,DB,0,0,0);
      if(!db)
      {
      	printf("FEHLER! Kann Verbindung mit Datenbank nicht herstellen! \n");
    	return 1;
      }
    


  • mysql_real_connect liefert einen NULL Pointer im Fehlerfall.

    Die Zeile:

    mysql = mysql_real_connect(mysql, eingabe().c_str(), "root","******", "notizen", 0,NULL, 0);
    

    löscht den Zeiger des von mysql_init erzeugten Objektes.
    mysql_errno bekommt anschliessend den NULL Pointer und mag das vermutlich gar nicht.

    Statt mysql mit dem Ergebnis von mysql_real_connect zu überschreiben, einfach nur auf != NULL prüfen (oder in Deinem Fall den Returnwert ignorieren - mysql_errno sollte das dann erledigen) - besser ist aber die direkte Prüfung.

    datenbank::datenbank():mysql(NULL), ergebnis_(NULL), reihe_(NULL) {
        // Datenbank initialisieren
        mysql = mysql_init(NULL);
        // Verbindung mit Datenbank herrstellen
        mysql_real_connect(mysql, eingabe().c_str(), "root","******", "notizen", 0,NULL, 0);
        fehlerpruefen();
    }
    


  • ich würd lieber mit exceptions arbeiten:

    void datenbank::fehlerpruefen() {
        int fehlerNummer=mysql_errno(mysql);
        if (fehlerNummer!=0) {
            throw MySQLException(fehlerNummer,mysql_error(mysql));
        }
    }
    

    MySQLException:

    class MySQLException:public std::exception{
        private:
            int fehlerNummer;
            std::string nachricht;
        public:
            MySQLException(int fehlerNummer,const std::string& nachricht ):fehlerNummer(fehlerNummer),nachricht(nachricht){}
            ~MySQLExcetion()throw(){}
            const char* what()const{//what ist eine methode aus std::exception die überschrieben werden muss
                return nachricht.c_str();
            }
            int fehlerNummer(){
                return fehlerNummer;
            }
    };
    

    und in der main:

    try{
        datenbank db;
    }
    catch(MySQLException& excep){
        std::cout<<"Error "<<excep.fehlerNummer()<<":"<<excep.what();
    }
    


  • Hmm aber wenn er exceptions benutzt, kann er auch gleich die c++ api nehmen oder ? und wenn er das macht gibts ja eh schon BadQuery BadConversation und co. sowie query.success() oder so in der art.. naja und dann würde ich die evtl in mit nem eigenen exception system benutzen bzw auf sie reagieren. oder direkt auf die mysqlpp exceptions reagieren.



  • Hmm aber wenn er exceptions benutzt, kann er auch gleich die c++ api nehmen oder ?

    Jein. Wenn er das interface wrappen will, ist er mit C deutlich besser dran, da funktionen+strukturen normalerweise einfacher gewrappt werden können als Klassen.



  • Hmm, stimmt in diesem Fall muss ich dir wiederum recht geben.


Anmelden zum Antworten