Unbehandelte Ausnahme nach Laden einer Datei



  • Erstens ist dein Vergleich

    input == NULL
    

    sinnlos. input ist ein Objekt, kein Zeiger.

    Zweitens bezweifle ich, dass du Binärdaten lesen/schreiben möchtest. Du kannst dafür auch einfach die Stream-Operatoren verwenden, die wurden nämlich schon in weiser Vorraussicht von C++ für alle Grunddatentypen (und std::string) überladen 😉

    Drittens, hier ein Schema, wie ich beim Lesen einer Datei vorgehen würde.

    int main()
    {
        std::ifstream is("blah.blubb");
    
        if(!is.is_open())
        {
            std::cout << "Fehler beim Öffnen der Datei" << std::endl;
            return 1;
        }
    
        is >> daten;
    
        if(!is.eof())
        {
            std::cout << "Fehler beim Lesen der Datei" << std::endl;
            return 1;
        }
    
        // is wird am Ende des Scopes automatisch geschlossen. Nennt sich RAII.
    }
    


  • 314159265358979 schrieb:

    Erstens ist dein Vergleich

    input == NULL
    

    sinnlos. input ist ein Objekt, kein Zeiger.

    Da hab ich einfach mal dem Autor des Buches vertraut, aber gut es jetzt besser zu wissen.

    314159265358979 schrieb:

    Zweitens bezweifle ich, dass du Binärdaten lesen/schreiben möchtest. Du kannst dafür auch einfach die Stream-Operatoren verwenden, die wurden nämlich schon in weiser Vorraussicht von C++ für alle Grunddatentypen (und std::string) überladen 😉

    Den Binärdatentyp habe ich in der aktuellen Version nicht mehr drin 🙂

    314159265358979 schrieb:

    Drittens, hier ein Schema, wie ich beim Lesen einer Datei vorgehen würde.

    int main()
    {
        std::ifstream is("blah.blubb");
    
        if(!is.is_open())
        {
            std::cout << "Fehler beim Öffnen der Datei" << std::endl;
            return 1;
        }
    
        is >> daten;
    
        if(!is.eof())
        {
            std::cout << "Fehler beim Lesen der Datei" << std::endl;
            return 1;
        }
    
        // is wird am Ende des Scopes automatisch geschlossen. Nennt sich RAII.
    }
    

    Bis auf den beiden if-Anweisungen hatte ich vorhin das selbe Schema verfolgt. Die Daten wurden nach dem Laden jedoch alle hintereinander angezeigt und nicht in der, für den Wert vorgesehenen Zeile.

    Edit:
    Habe gerade bemerkt, dass sich dieses "alles in einer Zeile Laden" mit einem "\n" beim Schreiben in die Datei umgehen lässt. Ist aber etwas umständlich, zumal das Ergebnis beim if(Input.good()) immernoch false bleibt (wobei ich mir ehrlich gesagt nichmal sicher bin, ob das auch was zu sagen hat).



  • Sorex schrieb:

    Da hab ich einfach mal dem Autor des Buches vertraut, aber gut es jetzt besser zu wissen.

    Welches Buch ist das? Hat der Autor die Initialen J.W.?

    Sorex schrieb:

    Den Binärdatentyp habe ich in der aktuellen Version nicht mehr drin 🙂

    Das hat damit nichts zu tun. Sobald du .read() aufrufst, liest du hier Binär.
    Mit >> liest man formatiert.



  • Hast du auch die Speicher-Methode mit angepasst? Die beiden müssen natürlich Hand in Hand arbeiten, poste optimalerweise nochmal deine jetzige Fassung beider Methoden.



  • Das ist das Problem, wenn man Unreg ist, man kann nicht editieren.

    Dir ist schon klar, dass du beim Speichern eine Datei mit Namen "Chrakter.ch" und NICHT "Charakter.ch" erstellst?



  • Aktuell sehen sie so aus:

    void Game::saveGame()
    {
    	std::cout << "\nWirklich speichern? Alter Spielstand wird dabei überschrieben\n"
    		      << "Bestätigen durch Eingabe von (J)a bzw (N)ein: ";
    	char str;
    	std::cin >> str;
    	if (str == 'j' || str == 'J')
    	{
    		std::ofstream Output("hero.ch");
    		if (Output == NULL)
    		{
    			std::cout << "\nDatei zum Speichern konnte nicht geöffnet werden!\n";
    		}
    		else
    		{
    
    		   Output.write((char*) &hero.attackPower_, sizeof(hero.attackPower_));
    		   Output.write((char*) &hero.defensePower_, sizeof(hero.defensePower_));
    		   Output.write((char*) &hero.hitPoints_, sizeof(hero.hitPoints_));
    		   Output.write((char*) &hero.hpMax_, sizeof(hero.hpMax_));
    		   Output.write((char*) &hero.mana_, sizeof(hero.mana_));
    		   Output.write((char*) &hero.manaMax_, sizeof(hero.manaMax_));
    		   Output.write((char*) &hero.level_, sizeof(hero.level_));
    		   Output.write((char*) &hero.exp_, sizeof(hero.exp_));
    		   Output.write((char*) &hero.expMax_, sizeof(hero.expMax_));
    		   Output.write((char*) &hero.money_, sizeof(hero.money_));
    		   Output.write((char*) &hero.creditPoints_, sizeof(hero.creditPoints_));
    		   Output << hero.name_;
    
    		   std::cout << "\nSpielstand erfolgreich gesichert\n";
    		}
    	    Output.close();
    	}
    	else if (str == 'n'|| str == 'N')
    	{
    		std::cout << "\nSpeichern abgebrochen\n";
    	}
    	else
    	{
    		std::cout << "\nFalsche Eingabe\n";
    	}
    }
    
    void Game::loadGame()
    {
        std::cout << "\nWirklich laden? Bisherige Erfolge werden gelöscht\n"
                  << "Bestätigen durch Eingabe von Ja bzw Nein: ";
        char str;
        std::cin >> str;
    
        if (str == 'j' || str == 'J')
        {
            std::ifstream Input("hero.ch");
            if(Input == NULL)
            {
                std::cout << "\nDatei konnte nicht geöffnet werden!\n";
            }
            else
            {  
    
               Input.read((char*) &hero.attackPower_, sizeof(hero.attackPower_));
               Input.read((char*) &hero.defensePower_, sizeof(hero.defensePower_));
               Input.read((char*) &hero.hitPoints_, sizeof(hero.hitPoints_));
               Input.read((char*) &hero.hpMax_, sizeof(hero.hpMax_));
               Input.read((char*) &hero.mana_, sizeof(hero.mana_));
               Input.read((char*) &hero.manaMax_, sizeof(hero.manaMax_));
               Input.read((char*) &hero.level_, sizeof(hero.level_));
               Input.read((char*) &hero.exp_, sizeof(hero.exp_));
               Input.read((char*) &hero.expMax_, sizeof(hero.expMax_));
               Input.read((char*) &hero.money_, sizeof(hero.money_));
               Input.read((char*) &hero.creditPoints_, sizeof(hero.creditPoints_));
               Input >> hero.name_;
    
                std::cout << "\nSpielstand erfolgreich geladen\n";
            }
            Input.close();
    
            if(Input.good())
               std::cout << "JA\n";
            else
               std::cout << "NEIN\n";
        }
        else if (str == 'n'|| str == 'N')
        {
            std::cout << "\nLaden abgebrochen\n";
        }
        else
        {
            std::cout << "\nFalsche Eingabe\n";
        }
    }
    

    Welches Buch ist das? Hat der Autor die Initialen J.W.?

    Das Buch nennt sich C++ für Spieleprogrammierer und ist von Heiko Kalista



  • bitmap.button schrieb:

    Das ist das Problem, wenn man Unreg ist, man kann nicht editieren.

    Dir ist schon klar, dass du beim Speichern eine Datei mit Namen "Chrakter.ch" und NICHT "Charakter.ch" erstellst?

    Ja, das war die Version von gestern.. hab sie danach auf hero.ch umgetauft (entstehen weniger Tippfehler xD)



  • Wie schon mehrfach erwähnt wurde: Verzichte lieber auf die read()/write() und verwende für alle Daten die Stream-Operatoren.

    @Pi: Hat der eof-Test bei deinem Code eigentlich einen tieferen Sinn?



  • CStoll schrieb:

    @Pi: Hat der eof-Test bei deinem Code eigentlich einen tieferen Sinn?

    Wenn das Ende erreicht wurde, ist alles glatt gelaufen. Wenn nicht, nicht. Ist doch logisch?



  • Erstens erinnere ich mich düster, daß eof erst nach einem erfolglosen Leseversuch gesetzt wird. Und zweitens: Was machst du, wenn in der Datei mehr steht als dein Lese-Operator erfasst hat?



  • CStoll schrieb:

    Erstens erinnere ich mich düster, daß eof erst nach einem erfolglosen Leseversuch gesetzt wird. Und zweitens: Was machst du, wenn in der Datei mehr steht als dein Lese-Operator erfasst hat?

    Im Normalfall lese ich alles aus. Will man das nicht, muss man anders vorgehen.
    Aber du hast wohl Recht, wenn du meinst, dass die Überprüfung mit .fail() besser ist, da immer funktioniert.



  • CStoll schrieb:

    Wie schon mehrfach erwähnt wurde: Verzichte lieber auf die read()/write() und verwende für alle Daten die Stream-Operatoren.

    @Pi: Hat der eof-Test bei deinem Code eigentlich einen tieferen Sinn?

    Hab das so gemacht, funktioniert auch wunderbar, nur das Ergebnis, was Input.good() liefert bleibt auch hier false.
    Aber warum ist das so? Ist das überhaupt von Belang oder kann ich das getrost ignorieren? 🙂


Anmelden zum Antworten