Du bist nicht angemeldet.

Stilllegung des Forums
Das Forum wurde am 05.06.2023 nach über 20 Jahren stillgelegt (weitere Informationen und ein kleiner Rückblick).
Registrierungen, Anmeldungen und Postings sind nicht mehr möglich. Öffentliche Inhalte sind weiterhin zugänglich.
Das Team von spieleprogrammierer.de bedankt sich bei der Community für die vielen schönen Jahre.
Wenn du eine deutschsprachige Spieleentwickler-Community suchst, schau doch mal im Discord und auf ZFX vorbei!

Werbeanzeige

1

12.12.2014, 18:40

C++ für Spieleprogammierer: Array von Instanzen in Dateien abspeichern - wie geht's?

Hallo in die Runde,

das Buch von Heiko Kalista ist insgesamt super aufgebaut. Hin und wieder ändere und ergänze ich die dortigen Listings, um zu sehen, was passiert.

Nun habe ich eine Frage zu Listing 8.10 auf Seite 254 "Instanzen in Dateien schreiben und auslesen": Das Listing ist logisch und nachvollziehbar, aber bezieht sich nur auf das Schreiben und Auslesen EINER Instanz.

Wie schreibe ich z.B. eine komplette Spielerliste, also ein Array, das analog zu Listing 7.9. auf Seite 205/206 erstellt wurde, in eine Datei und lese die Liste wieder aus? Habe verschiedene Versuche mit der Liste unternommen und das Programm ist immer abgestürzt. Kann es daran liegen, dass letztlich 2 Zeiger aufeinandertreffen? Einmal der der Spielerliste und einmal der "char*"-Zeiger der ofstream- und ifstream-Objekte?

Vielen Dank im voraus für Eure Antworten, freue mich auf regen Austausch.


Beste Grüße, Globalman68

BlueCobold

Community-Fossil

Beiträge: 10 738

Beruf: Teamleiter Mobile Applikationen & Senior Software Engineer

  • Private Nachricht senden

2

12.12.2014, 19:17

5 = 1 + 1 + 1 + 1 + 1
Teamleiter von Rickety Racquet (ehemals das "Foren-Projekt") und von Marble Theory

Willkommen auf SPPRO, auch dir wird man zu Unity oder zur Unreal-Engine raten, ganz bestimmt.[/Sarkasmus]

3

12.12.2014, 19:31

Hallo BlueCobold,

heisst also konkret, einzelne Instanzen statt eines Arrays zu erzeugen und für jede Instanz ein eigenes ofstream- und ifstream-Objekt zu erstellen?

Beste Grüße, Globalman

4

12.12.2014, 19:33

Nein, das heißt konkret den Operator[] zu benutzen...

C-/C++-Quelltext

1
2
for(std::size_t i = 0U; i < 5U; ++i)
    //mach was mit array[i]


MfG
Check

5

12.12.2014, 20:05

Hallo Checkmateing,

hab ich schon versucht,

also eine Schleife um die ofstream- und ifstream-Objekte "gebaut", um dann die einzelnen Spieler in die Datei zu schreiben und wieder auszulesen.

Hier ein Codeauschnitt (der Einfachheit halber gehen wir davon aus, dass sich alles in der "main.cpp"-Datei abspielt):

#include <iostream>
#include <fstream>

using namespace std;


class CSpieler

{
public:

int m_Punkte;
char m_Name[20];
};


int main()
{

CSpieler *pSpielerliste = NULL;
int anzahl = 10; //Festlegung auf 10 Spieler, auf Abfrage via cin wurde hier verzichtet
pSpielerliste = new CSpieler[anzahl];

...
...
...
//Zum Einlesen


ofstream Output("Spielstand.sps", ios::binary);

for (int i = 0; i < anzahl; ++i)
{

Output.Write((char *)&pSpielerliste[i], sizeof (pSpielerliste[i]));

}
Output.close ();


//Zur Wiederausgabe

ifstream Input ("Spielstand.sps", ios::binary);

for (int y = 0; y < anzahl; ++y)
{

Input.read ((char *)&pSpielerliste[y], sizeof (pSpielerliste[y]));

cout << "\n" << pSpielerliste[y].m_Name << " hat bisher "<< pSpielerliste[y].m_Punkte << " erreicht." << endl;
}
Input.close ();



delete[] pSpielerliste;
pSpielerliste = NULL;


return 0;
}

So müsste es eigentlich funktionieren, aber das Programm stürzt hier immer ab, obwohl vorher beim Kompilieren keinen Fehlermeldung angezeigt wird.

?(
[/i][/i]

Dieser Beitrag wurde bereits 4 mal editiert, zuletzt von »Globalman68« (12.12.2014, 21:03)


BlueCobold

Community-Fossil

Beiträge: 10 738

Beruf: Teamleiter Mobile Applikationen & Senior Software Engineer

  • Private Nachricht senden

6

12.12.2014, 20:30

Wenn Du die Datei 5mal erstellst, wird das wohl nix. Du musst sie natürlich nur einmal erstellen und alle 5 Instanzen reinschreiben. Aber nicht einfach per (char *)&pSpielerliste[i], sizeof (pSpielerliste[i]). Oder wird im Buch ein einzelnes Objekt so gespeichert?
Teamleiter von Rickety Racquet (ehemals das "Foren-Projekt") und von Marble Theory

Willkommen auf SPPRO, auch dir wird man zu Unity oder zur Unreal-Engine raten, ganz bestimmt.[/Sarkasmus]

7

12.12.2014, 20:37

@BlueCobold

hatt einen Tippfehler im Listing, jetzt müsste es so passen: &pSpielerliste

Es wird mit einer Schleife jede Instanz aufgerufen und soll in ein und derselben Datei abgespeichert werden.

Ggfs. nach ios::binary noch ios::app dranhängen, damit die vorherige Instanz nicht überschrieben wird. Hatte ich auch schon aber trotzdem stürzt das Programm immer noch ab.

BlueCobold

Community-Fossil

Beiträge: 10 738

Beruf: Teamleiter Mobile Applikationen & Senior Software Engineer

  • Private Nachricht senden

8

12.12.2014, 20:42

Nun, Du öffnest die Datei noch immer 5mal und schließt sie aber nur einmal. Warum Du sie 5mal statt einmal öffnest, ist mir noch immer nicht klar.
Teamleiter von Rickety Racquet (ehemals das "Foren-Projekt") und von Marble Theory

Willkommen auf SPPRO, auch dir wird man zu Unity oder zur Unreal-Engine raten, ganz bestimmt.[/Sarkasmus]

9

12.12.2014, 20:46

@ BlueCobold 2

...ah ok, ich glaub ich weiss, was Du mir sagen willst:

Statt einer Liste mit Instanzen einfach mehrere Instanzen einzeln erzeugen (z.B. CSpieler Spieler 1 bis 3) und dann einfach

ofstream Output ("Spielstand.sps", ios:binary | ios:app)

Output.Write ((char *)&Spieler1, sizeof(Spieler1));
Output.Write ((char *)&Spieler2, sizeof(Spieler3));
Output.Write ((char *)&Spieler3, sizeof(Spieler3));

Output.Close

und beim Auslesen mit Input dann aumgekehrt?

10

12.12.2014, 20:48

Mach mal Klammern um pSpielerliste[index], also &(pSpielerliste[index]). Keine Ahnung, mit welcher Priorität die Operatoren angewandt werden. Wenn & erst angewandt wird, dann wird auf den Speicherbereich nach der Stelle, an der der Pointer gespeichert ist, zugegriffen, statt auf pSpielerliste+index*Größe von CSpieler. Einen Compilerfehler gibt es nicht, da der Pointer in einen char* umgewandelt wird und das geht mit jedem Pointer, auch wenn er nicht der ist, den man will.

Pack mal die Erstellung der Datei vor die Schleife und nicht in sie hinein.
Cube Universe
Entdecke fremde Welten auf deiner epischen Reise durchs Universum.

Werbeanzeige