binäres Speichern / Lesen



  • Hallo zusammen!

    Habe ein Progrämmelche geschrieben, das die Rangliste von Spielern in einer Datei binär abspeichert und zwar in der Form:
    <Name> <Wins> <Losses> <Ranglistenpunkte>
    z.B:
    MasterBlaster 100 60 1024
    Bei jedem neuen Einfügen wird die Datei in ein Array eingelesen und dieses sortiert und falls, der Spielername des neuen Datensatzes bereits in einem alten vorhanden ist, so wird dieser nur aktualisiert.

    Umgesetzt habe ich das wie folgt:

    /************************************************
    *   Prozedur FExist                           
    ************************************************* 
    *   ->   Prüft Existenz einer Datei        
    *   ->   Parameter:  - name == zu prüf. Datei   
    ************************************************/
    bool FExist(char* name)
    {
      ifstream source;
      source.open(name,ios::binary|ios::in);
      if (!source) {return true; }
      else         {CloseFile(name); return false;}
    }
    
    /************************************************
    *   Prozedur AppendData                         
    ************************************************* 
    *   ->   Fügt neue Daten in Sortierung ein      
    *   ->   Parameter:  - name == zu prüf. Datei   
    *                    - n    == Spielername      
    *                    - w    == Wins             
    *                    - l    == Losses           
    *                    - r    == Rating           
    ************************************************/
    bool AppendData(char* name,char* n, int w, int l, int r)
    {
      if (FExist(name)) { WriteData(name, n, w, l, r); }
      else
      {
         fstream File(name, ios::in|ios::binary);
         int pos=-1; const int zeilen=DataCount(name); bool flag=false;
         int z=DataCount(name);
         player p[zeilen+1];
         for (int x=0;x<zeilen;x++)
         { 
            File.read(reinterpret_cast<char*>(&p[x]), sizeof(p[x]));
            if (p[x].name==n) {pos=x; flag=true;}
         }
         CloseFile(name);
         if (flag)
         {
           p[pos].name=n;p[pos].wins=w;p[pos].losses=l;p[pos].rating=r;
           z=z-1;
         }
         else
         {
           p[z].name=n;p[z].wins=w;p[z].losses=l;p[z].rating=r;
         }
         // Datensätze sortieren
         player tmp;
         if (z!=1)
         {
           for (int y=0;y<=z-1;y++)
           {
             pos=y;  // Vorläufiges Max
             for (int x=y+1;x<=z;x++)
             { // Neues Maximum gefunden?
               if (p[x].rating>p[pos].rating) {pos=x;}
             }
             if (pos!=y)
             {
                tmp.name=p[pos].name;
                tmp.wins=p[pos].wins;
                tmp.losses=p[pos].losses;         
                tmp.rating=p[pos].rating;
                p[pos].name=p[y].name;
                p[pos].wins=p[y].wins;
                p[pos].losses=p[y].losses;
                p[pos].rating=p[y].rating;
                p[y].name=tmp.name;
                p[y].wins=tmp.wins;
                p[y].losses=tmp.losses;
                p[y].rating=tmp.rating;
             }
           }
         }
         // Daten neu schreiben
         fstream FS(name, ios::out|ios::trunc);
         CloseFile(name);
         for (int d=0; d<=z; d++)
         {
            WriteData(name, p[d].name, p[d].wins, p[d].losses, p[d].rating);             
         }
       }
    }
    
    /************************************************
    *   Prozedur WriteData                       
    ************************************************* 
    *   ->   Schreibt neuen Datensatz               
    *   ->   Parameter:  - name == zu prüf. Datei   
    *                    - n    == Spielername      
    *                    - w    == Wins             
    *                    - l    == Losses           
    *                    - r    == Rating           
    ************************************************/
    bool WriteData(char* name, char* n, int w, int l, int r)
    {
         player p;
         p.name = n; p.wins=w; p.losses=l; p.rating=r;
         fstream File(name, ios::out|ios::app|ios::binary); 
         File.write(reinterpret_cast<const char*>(&p), sizeof(p));
         CloseFile(name);
    }
    
    /************************************************
    *   Prozedur ReadData                          
    ************************************************* 
    *   ->   Liest Datensatz aus einer Datei        
    *   ->   Parameter:  - name == zu prüf. Datei   
    ************************************************/
    bool ReadData(char* name)
    {
      ifstream File;
      File.open(name, ios::binary|ios::in);
      if (File)
      {
        const int z=DataCount(name);
        player pfield[z];
        for (int x=0;x<z;x++)
        {
          File.read(reinterpret_cast<char*>(&pfield[x]), sizeof(pfield[x]));
          cout << pfield[x].rating << " " << pfield[x].name <<" "
               << pfield[x].wins << "/" << pfield[x].losses << endl;
        }
        char c; cin >>c;
      }
      CloseFile(name);
    }
    
    /************************************************
    *   Prozedur DataCount                          
    ************************************************* 
    *   ->   Gibt Anzahl Datensätze zurück          
    *   ->   Parameter:  - name == zu prüf. Datei   
    ************************************************/
    int DataCount(char* name)
    {
      fstream File(name, ios::in|ios::binary);
      player p; int x=-1;
      while (!File.eof())
      {
        File.read(reinterpret_cast<char*>(&p), sizeof(p));
        x++;
      }
      CloseFile(name);
      return x;
    }
    
    /************************************************
    *   Prozedur CloseFile                          
    ************************************************* 
    *   ->   Schließt Datei u. setzt Status zurück  
    *   ->   Parameter:  - name == zu prüf. Datei   
    ************************************************/
    bool CloseFile(char* name)
    {
      fstream File(name);
      File.close();
      File.clear();
    }
    

    [

    Wenn ich testweise eine main() bastel und folgendes teste:

    AppendData("data.txt", "D4",1,2,7656);
    AppendData("data.txt", "D3",3,4,1025);
    AppendData("data.txt", "D2",2,3,8555);
    AppendData("data.txt", "D1",666,999,9999);
    AppendData("data.txt", "D1",666,999,1030);
    ReadData("data.txt");
    

    => Funktionierts ohne Probleme!, Ausgabe:
    8555 D2 2/3
    7656 D4 1/2
    1030 D1 666/999
    1025 D3 3/4

    Kommentiere ich jedoch AppendData's aus, so gehts nimmer!??? 😡

    //AppendData("data.txt", "D4",1,2,7656);
    //AppendData("data.txt", "D3",3,4,1025);
    //AppendData("data.txt", "D2",2,3,8555);
    //AppendData("data.txt", "D1",666,999,9999);
    //AppendData("data.txt", "D1",666,999,1030);
    ReadData("data.txt");
    

    Ausgabe: 😕
    8555 ↑ïêEÃE°♣ 2/3
    7656 data.txt 1/2
    1030êE
    ÃE°♣ 666/999
    1025 Õâý↑ïêE*ÃE°♣ 3/4

    Die Datei muss danach auch gelöscht werden, weil sie diese Einträge tatsächlich zu beinhalten scheint und somit unbrauchbar ist!
    Kann mir wer sagen wo hier der Fehler liegt?
    Bin darüber hinaus auch an Verbesserungsvorschlägen interessiert!

    Danke & Grüße
    Kai



  • /************************************************
    *   Prozedur DataCount                          
    *************************************************
    

    Prozeduren haben keinen Rückgabewert, Rückgabewerte haben Funktionen 🙂

    Hast du schonmal überprüft ob der Wert den DataCount zurück gibt richtig ist?

    Ansonsten solltest du mal nach std::string googlen und in der FAQ nach Datei ein-/auslesen suchen.



  • Funktionen mit void als Rückgabetyp nennt man in C++ aber üblicherweise dennoch Funktionen, Prozedur ist ein Begriff, der häufiger bei VB auftritt AFAIK.



  • Prozedur ist ein Begriff, der häufiger bei VB auftritt AFAIK.

    Basic weis ich jetzt nicht aber bei Pascal tritt er auf. In C/C++ ist halt alles eine Funktion, viel einfacher 😃 👍



  • Junx... streitet euch bitte nicht um solche Kleinigkeiten! Dafür hab ich den Post sicherlich nicht gemacht!

    Kann sich jemand das Posting mal ernsthaft durchsehen, vielleicht bleibt mir dann weitere Arbeit erspart?

    Ich habe währenddessen von 0 angefangen und habe meine Struktur statt mit "char* name" mit "char name[20]" umgebaut. Das Lesen & Schreiben funktioniert hier, aber das Vergleichen von Datensätzen nicht...

    bool CheckData(char* file, Player pnew)
    {
      fstream File(file, ios::in|ios::binary); 
      if (File.is_open()) 
      { 
        Player p; 
        while (File.read((char*)&p, sizeof(p))) 
        {
          if (pnew.name==p.name) // Vergleich zieht nicht ...
          {  
              cout << "Spielername ist bereits vergeben!!!" << endl;
              File.close();
              return true;
          }
        } 
      }
      File.close();
      return false;
    }
    

    Jemand hierfür ne Idee? Muss ich die Variablen pnew & p in einer Schleife miteinander vergleichen d.h. komponentenweise, da Array of char? Gibbet dafür vielleicht nen compare-Befehl oder hat wern Coding-Schnipsel für sowas?

    Danke & Grüße
    Kai



  • Hallo,

    H4ll0w33n schrieb:

    Muss ich die Variablen pnew & p in einer Schleife miteinander vergleichen

    du kannst, wenn du Lust und Zeit hast, aber das gibt es eigentlich schon in Form der Funktion strcmp:

    http://msdn.microsoft.com/library/default.asp?url=/library/en-us/vccore98/HTML/_crt_strcmp.2c_.wcscmp.2c_._mbscmp.asp

    MfG


Anmelden zum Antworten