File wird nicht (korrekt) gelesen



  • Hallo

    Ich habe folgendes Problem, wobei ich denke, dass es sich mal wieder um ein Denkfehler handelt oder ich einfach Tomaten auf den Augen habe. Ich habe mir für ein kleines Spiel eine Klasse namens level_loader geschrieben mit deren Hilfe ich alle in einem Ordner vorhandenen Level auslesen will. Das klappt für das erste Level und die dazugehörige Datei namen level1.dat auch hervorragend , aber die zweite Datei wird nicht richtig gelesen. es werden nur Nullen gelesen, obwohl deinitiv andere Zahlen in der Datei stehen. Hier mal der Code:

    #include "level_loader.h"
    #include <boost/filesystem.hpp>
    #include <boost/lexical_cast.hpp>
    #include <string>
    #include "data.h"
    
    using namespace boost::filesystem;
    using boost::lexical_cast;
    
    using namespace chrische;
    
    level_loader::level_loader(void)
    {
    }
    
    level_loader::~level_loader(void)
    {
    }
    
    chrische::level level_loader::load( const std::string file_name )
    {
    	file_to_read_out.open(file_name.c_str());
    	int temp = 0;
    	chrische::stone temp_stone;
    	chrische::level temp_level;
    	for(size_t i=0; i<13; ++i)
    		for (size_t k=0; k<20; ++k)
    		{
    			file_to_read_out >> temp;
    			temp_stone.rest_hits = temp;
    			temp_stone.set_x(k);
    			temp_stone.set_y(i);
    			temp_level.stones.push_back(temp_stone);
    		} // for (size_t k=0; k<15; ++k)
    		file_to_read_out.close();
    	return temp_level;
    }
    
    std::vector<chrische::level> chrische::level_loader::load_all_levels()
    {
    	bool load_again = true;
    	int file_name_counter = 1;
    	std::vector<chrische::level> temp_level;
    	while(load_again)
    	{
    		std::string filename = "level\\level" + lexical_cast<std::string>(file_name_counter) + ".dat";
    		load_again = false;
    		if(exists(filename))
    		{
    			temp_level.push_back(load(filename));
    			load_again = true;
    			file_name_counter++;
    			get_data().whole_level++;
    		}
    	} // while(load_again)
    	return temp_level;
    }
    

    Die Datei level2.dat wird gefunden und auch "gelesen", aber eben nur Nullen. Weiß jemand, was ich hier falsch mache.

    chrische



  • Hmm, hast du mal probiert, ein lokales ifstream-Objekt zu benutzen? Vielleicht sind noch irgendwelche Fehlerflaggen gesetzt.

    P.S.: Übrigens hat Boost.Filesystem ein paar mehr Funktionalitäten als exists 😉



  • Hallo

    Das klappt. Danke. Das es noch ein paar mehr Funktionen gibt, weiß ich und ich habe auch schon einige davon genutzt.

    chrische



  • Naja, ich meinte das vor allem im Hinblick auf die Art und Weise wie du iterierst, wie du den Dateinamen zusammenbaust und wie du die Datei dann öffnest.



  • Hallo

    .filmor schrieb:

    Naja, ich meinte das vor allem im Hinblick auf die Art und Weise wie du iterierst, wie du den Dateinamen zusammenbaust und wie du die Datei dann öffnest.

    Wenn du so etwas schreibst, hast du doch sicher eine Idee, wie es besser geht. Lass mich doch an deinem Wissen teilhaben. Ich habe mich noch nicht iengehend damit beschäftigt, weil es bisher auch so immer gut geklappt hat. Ich bin aber sehr an effektiveren Methoden interessiert.

    chrische



  • Okay. Ich hatte nur angenommen, dass sei ein Prototyp.

    Es gibt in Boost.Filesystem einen directory_iterator. Mit diesem kannst du über den Inhalt eines Verzeichnisses iterieren. Aber ich weiß grad nicht, wie wichtig der ist, eigentlich tuts deine Funktion ja wahrscheinlich für deine Dateien am Besten. Aber da kannst du noch einiges verbessern, indem du boost::filesystem::path und boost::filesystem::ifstream verwendest. Ersteres erlaubt dir plattformunabhängige Pfade zusammenzusetzen, letzteres kann diese direkt als Argument annehmen, statt den Umweg über std::string und const char* zu nehmen:

    chrische::level level_loader::load( const path& file_name )
    {
        boost::filesystem::ifstream file_to_read_out (file_name);
        int temp = 0;
        chrische::stone temp_stone;
        chrische::level temp_level;
        for(size_t i=0; i<13; ++i)
            for (size_t k=0; k<20; ++k)
            {
                file_to_read_out >> temp;
                temp_stone.rest_hits = temp;
                temp_stone.set_x(k);
                temp_stone.set_y(i);
                temp_level.stones.push_back(temp_stone);
            } // for (size_t k=0; k<15; ++k)
        return temp_level;
    }
    
    std::vector<chrische::level> chrische::level_loader::load_all_levels()
    {
        bool load_again = true;
        int file_name_counter = 1;
        std::vector<chrische::level> temp_level;
        path level_root = "level";
        while(load_again)
        {
            path filename = level_root / "level" + lexical_cast<std::string>(file_name_counter) + ".dat";
            load_again = false;
            if(exists(filename))
            {
                temp_level.push_back(load(filename));
                load_again = true;
                file_name_counter++;
                get_data().whole_level++;
            }
        } // while(load_again)
        return temp_level;
    }
    

    Mit directory_iterator kann man da vielleicht noch was machen, aber ich weiß nicht, ob der die Reihenfolge einhält.



  • Hallo

    Vielen Dank für die Mühe. Viel küzer sieht es am Ende aber wirklich nicht aus (ist natürlich keine ritik, sondern nur ein Feststellung).

    chrische



  • Das Ganze hat aber den Vorteil, dass du dich nicht um die richtige Schreibweise des Pfades (Pfadtrenner) kümmern mußt. Falls du plattformunabhängig programmieren oder anderssprachige Windowssystem nutzen willst ist das schon gut.


Anmelden zum Antworten