Dateilesen: Wo liegt derFehler?



  • Hallo liebe Community!

    Ich bin neu hier im Forum und auch neu in C++.
    Für mein kleines Spiel möchte ich die Statistiken der Spieler in die Datei "Statistiken.txt" speichern, das funktioniert soweit auch ganz gut.

    In der Datei steht dann Beispielsweise:

    Klaus 14
    Peter 2
    Hans 78
    Lukas 5
    Leon 1
    

    Nun die Funktion, die die Statistiken ausgeben und sie gleichzeitig auch sortieren soll:

    int StatistikOutput() 
    {
    	struct Daten
    	{
    		string Name;
    		int Punkte;
    
    		string SortedName;
    		int SortedPunkte;
    
    	};
    	Daten SpielerDaten[256];
    
    	// Datei Lesen
    	ifstream fin("Statistiken.txt", ifstream::in);
    
    	// Zeilen der Datei zählen
    	int Rows = 0;
    	string unused;
    	while ( getline(fin, unused) ) Rows++;
    
    	// Erfolgreiches Öffnen überprüfen
    	if (!fin.is_open())
    	{
    		cout << KonnteStatsNichtLaden << endl;
    		return -1;
    	}
    	else // Highscores laden und in Variablen speichern
    	{
                    // der Fehler liegt möglicherweise hier
    		int i = 1;
    		while (fin >>  SpielerDaten[i].Name >> SpielerDaten[i].Punkte)
    		{
    			i++;
    		}
    	}
    
    	// Datei schließen
    	fin.close();
    
    	// Highscores sortieren
    	int PunkteSave = 0;
    	string NameSave;
    	for (int i = 1; i <= Rows;  i++)
    	{
    		if (SpielerDaten[i].Punkte < SpielerDaten[i + 1].Punkte)
    		{
    			PunkteSave = SpielerDaten[i].Punkte;
    			NameSave   = SpielerDaten[i].Name;
    
    			SpielerDaten[i].Punkte	= SpielerDaten[i + 1].Punkte;
    			SpielerDaten[i].Name	= SpielerDaten[i + 1].Name;
    
    			SpielerDaten[i + 1].SortedPunkte = PunkteSave;
    			SpielerDaten[i + 1].SortedName	 = NameSave;
    		}
    	}
    
    	// Sortierte Highscores ausgeben
    	cout << "Versuche:" << "	Name:"<< endl;
    
    	for (int i = 1; i <= Rows;  i++)
    	{
    		cout << SpielerDaten[i].SortedPunkte << "		" << SpielerDaten[i].SortedName << endl;
    	}
    
    	system("PAUSE");
    	system("CLS");
    	return 1;
    }
    

    Das, was dann aber angezeigt wird, sieht so aus:

    Versuche:		Name:
    -858993460
    -858993460
    -858993460
    -858993460
    -858993460
    

    Es sollte aber so aussehen:

    Versuche:		Name:
    1				Leon
    2				Peter
    5				Lukas
    14				Klaus
    78				Hans
    

    Wo liegt der Fehler?
    Hoffe auf Lösung..

    MfG Trampeltier



  • Hallo Trampeltier,

    willkommen im C++-Forum.

    Dein Fehler liegt darin, dass DU die Datei liest, um die Zeilen zu zählen (was i.Grunde unnötig ist!) und anschließend versuchst, die Daten zu lesen.
    Geht natürlich nicht, weil Du je vorher schon das Datei-Ende erreicht hast.

    Besser: mache aus 'SpielerDaten' einen std::vector, lasse den Code des Zeilenzählens einfach weg und füge bei Zeile 34 noch ein 'push_back' eines Datensatzes in den vector hinzu.

    Gruß
    Werner



  • .. da sind noch mehr Fehler drin.
    Wichtig: bei Feldern und Containern der Größe N läuft der Index stets von 0 bis (N-1) und nicht von 1 bis N (so wie bei FORTRAN)

    anbei eine gekürzte, korrigierte Fassung:

    #include <algorithm> // sort
    #include <fstream>
    #include <string>
    #include <iostream>
    #include <vector> // vector (s. SpielerDaten)
    
    using namespace std;
    
    int StatistikOutput()
    {
        struct Daten
        {
            string Name;
            int Punkte; 
            bool operator<( const Daten& b ) const
            {
                return Punkte > b.Punkte; // mehr Punkte stehen vorn!
            }
        };
        // Daten SpielerDaten[256]; // C-like
        vector< Daten > SpielerDaten;
    
        {   // ---  Datei Lesen
            ifstream fin("Statistiken.txt");
            // Erfolgreiches Öffnen überprüfen
            if (!fin.is_open())
            {
                cout << KonnteStatsNichtLaden << endl;
                return -1;
            }
    
            // Highscores laden und in Variablen speichern
                    // der Fehler liegt möglicherweise hier -> Nö
            for( Daten satz; fin >> satz.Name >> satz.Punkte; )
            {
                SpielerDaten.push_back( satz );
            }
        }
    
        // Highscores sortieren
        sort( SpielerDaten.begin(), SpielerDaten.end() );
    
        // Sortierte Highscores ausgeben
        cout << "Versuche:" << "    Name:"<< endl;
    
        for (int i = 0; i < SpielerDaten.size();  i++)
        {
            cout << SpielerDaten[i].Punkte << "       " << SpielerDaten[i].Name << endl;
        }
    
        system("PAUSE");
        system("CLS");
        return 1;
    }
    

    Gruß
    Werner



  • Ich verstehe nicht, wieso du bei den Arrays immer bei 1 anfängst. Das erste Element wird mit 0 abgefragt:

    SpielerDaten[0].bla();
    

    Edit: Hach, zu langsam 🙂



  • Vielen Dank Werner!
    Durch dich habe ich das Problem beseitigt!
    Vector kannte ich bisher noch nicht (wie gesagt ich bin neu) und dass man die Punkte so leicht sortieren kann wusste ich auch nicht. 🙂

    Ich hätte die Punkte "Versuche" nennen sollen, denn je mehr Versuche man bekommt, desto schlechter (konntest du nicht wissen); Folglich mache ich

    return Punkte > b.Punkte
    

    zu

    return Punkte < b.Punkte
    

    .

    kralo9 schrieb:

    Ich verstehe nicht, wieso du bei den Arrays immer bei 1 anfängst. Das erste Element wird mit 0 abgefragt:

    SpielerDaten[0].bla();
    

    Edit: Hach, zu langsam 🙂

    Das ist etwas, was ich mir angewöhnt habe. Hehe. Danke fürs aufmerksam machen!

    Soo, Code funktioniert; Vielen Dank

    MfG Trampeltier



  • Trampeltier schrieb:

    kralo9 schrieb:

    Ich verstehe nicht, wieso du bei den Arrays immer bei 1 anfängst. Das erste Element wird mit 0 abgefragt:

    SpielerDaten[0].bla();
    

    Edit: Hach, zu langsam 🙂

    Das ist etwas, was ich mir angewöhnt habe. Hehe. Danke fürs aufmerksam machen!

    Soo, Code funktioniert; Vielen Dank

    MfG Trampeltier

    Dann aber schnell mal wieder abgewöhnen 😉


Anmelden zum Antworten