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

Errschaffer

Alter Hase

  • »Errschaffer« ist der Autor dieses Themas

Beiträge: 865

Wohnort: Frankfurt

  • Private Nachricht senden

1

27.01.2009, 14:55

Speichern/Laden von Listen?

Hallom
wollte man fragen ob man beim speichern und laden von Listen was besonderes beachten muss weil bei mir klappt das nicht so wirklich.

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
bool CKundenVerwaltung::m_Laden ()
{
    ifstream Input("Kunden.ku",ios::binary);
    Input.read   ((char*) &m_lKundenNormal,sizeof (m_lKundenNormal));
    Input.close ();

    if (Input==NULL)
    return false;

    else 
    return true;
}



Das Programm funktioniert ja und er erstellt mir auch die Datei nur wenn ich Kunden erstelle und dann speiche und dann beim nächsten Programmstart anzeigen möchte kommt nichts.

Ich hab im Internet gelesen das man da was besonders beachten muss ?!
Hab allerdings nicht wirklich eine konrekte Antwort gefunden.

2

27.01.2009, 14:58

Verkettete Listen (std::list) sind nicht wie dynamische Arrays (std::vector) an einem Stück, sondern irgendwie über den Arbeitsspeicher verteilt, wobei jedes Element auf das nächste und vorherige einen Zeiger hat. Deshalb funktioniert das binäre Schreiben nicht so, wie du möchtest.

Du müsstest also mit einem Iterator durchgehen und die Werte als Text speichern.

Nox

Supermoderator

Beiträge: 5 272

Beruf: Student

  • Private Nachricht senden

3

27.01.2009, 15:04

Vorallem wäre es mir neu, dass std:: nativ das serialisieren beherrschen würde. Du musst dir da wahrscheinlich was von Hand stricken. z.B. kannst du sowas machen:

C-/C++-Quelltext

1
2
3
file << liste.size();
for(std::list<...>::iterator it = liste.begin(); it != liste.end(); ++it)
file << *it;

Lesen analog (alles pseudocode)
PRO Lernkurs "Wie benutze ich eine Doku richtig"!
CONTRA lasst mal die anderen machen!
networklibbenc - Netzwerklibs im Vergleich | syncsys - Netzwerk lib (MMO-ready) | Schleichfahrt Remake | Firegalaxy | Sammelsurium rund um FPGA&Co.

David Scherfgen

Administrator

Beiträge: 10 382

Wohnort: Hildesheim

Beruf: Wissenschaftlicher Mitarbeiter

  • Private Nachricht senden

4

27.01.2009, 15:21

Dazu musst du für deine Klasse folgende Operatoren definieren:

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
std::ostream& operator <<(std::ostream& lhs, const DeineKlasse& rhs)
{
    // Hier die Daten deines Objekts in den Stream schreiben

    // oder eine Methode aufrufen, die das erledigt.

    // ...

    return lhs;
}

std::istream& operator >>(std::istream& lhs, DeineKlasse& rhs)
{
    // Hier die Daten deines Objekts aus dem Stream lesen

    // oder eine Methode aufrufen, die das erledigt.

    // ...

    return lhs;
}

NicoWe

Treue Seele

Beiträge: 126

Wohnort: Bielefeld / NRW

  • Private Nachricht senden

5

27.01.2009, 18:59

Du musst die Operatren selber schreiben, weil, wenn du einfach die Klasse in die Datei schreibst, es zu Problemen mit Pointern kommt. Du kannst normale Variablen einfach in einen Char casten:

Quellcode

1
2
char* out=new char[sizeof(Variablentyp)];
out=reinterpret_cast<char*>(Variable);

(nur pseudocode)

wenn du dies mit einem Pointer machst wird nur eine Adresse in die Datei geschrieben, und beim Auslesen kann das Programm mit dieser Addresse nichts mehr anfangen, weil sie ungültig ist.
Das Problem kannst du ganz einfach lösen, ich muss aber off und schreib se dir net ;) Kannst entweder so lange warten bis jemand anderes sie postet oder selber probieren
Erfolg ist die Fähigkeit, von einem Misserfolg zum anderen zu gehen,
ohne seine Begeisterung zu verlieren.
-Winston Churchill-

David_pb

Community-Fossil

Beiträge: 3 886

Beruf: 3D Graphics Programmer

  • Private Nachricht senden

6

27.01.2009, 19:11

Zitat von »"NicoWe"«

Du musst die Operatren selber schreiben, weil, wenn du einfach die Klasse in die Datei schreibst, es zu Problemen mit Pointern kommt. Du kannst normale Variablen einfach in einen Char casten:

Quellcode

1
2
char* out=new char[sizeof(Variablentyp)];
out=reinterpret_cast<char*>(Variable);

(nur pseudocode)


Eher so:

C-/C++-Quelltext

1
char* out = reinterpret_cast<char*>( &variable );

7

27.01.2009, 19:14

Zitat von »"NicoWe"«

Quellcode

1
2
char* out=new char[sizeof(Variablentyp)];
out=reinterpret_cast<char*>(Variable);

C-/C++-Quelltext

1
2
3
char* out=new char[sizeof(VarType)+1];
out=reinterpret_cast<char>(Var);
out[sizeof(VarType)]='\0'

also zumindest das geht, auch wenns äußerst unkonventionell und leistungsverschwendung ist.

8

27.01.2009, 19:44

Wenn man binär schreiben oder lesen will, muss man dem std::fstream noch das Flag std::ios::binary übergeben. Dann kann man die Methoden write() und read() benutzen. Aber ich würde Text ehrlich gesagt vorziehen. Die Handhabung ist einfacher und meistens reicht es auch. Bei binärem Modus kann man sich auch relativ schnell den Speicher zerschreiben.

Zitat von »"PCShadow"«

C-/C++-Quelltext

1
2
3
char* out=new char[sizeof(VarType)+1];
out=reinterpret_cast<char>(Var);
out[sizeof(VarType)]='\0'

also zumindest das geht, auch wenns äußerst unkonventionell und leistungsverschwendung ist.
Das geht mit Sicherheit nicht. Du kannst weder einen char einem char* zuweisen, noch zu char reinterpret_casten (war wahrscheinlich ein Schreibfehler). Und was sollte die Nullterminierung bringen? Das char* hat nichts mit einem C-String zu tun... Abgesehen davon hättest du da ein Memory-Leak und undefiniertes Verhalten, wenn der Code kompilieren würde. Und wie David_pb schon andeutete, sollte man den Zeiger und nicht den Speicher selbst umwandeln...

Naja, gerade wegen solcher Dinge wäre es vielleicht ratsamer, nicht binär zu arbeiten.

9

27.01.2009, 20:04

korrektur:

Quellcode

1
2
3
char* out=new char [sizeof(VarType)+1];
memcpy(out, Var, sizeof(Vartype));
out[sizeof(VarType)];

damit kann man eine Variable beliebigen Typs zum Speichern im textformat in einen C-String umwandeln ;)
ist aber wie gesagt unkonnventionell und leistungsverschwendung -> ich würds auch nicht machen, aber das ging mir halt bei NicoWes Pseudocode durch den Kopf ;)

David_pb

Community-Fossil

Beiträge: 3 886

Beruf: 3D Graphics Programmer

  • Private Nachricht senden

10

27.01.2009, 20:35

korrektur:

Quellcode

1
2
3
char* out=new char [sizeof(VarType)+1];
memcpy(out, &Var, sizeof(VarType));
out[sizeof(VarType)] = '\0';

Werbeanzeige