Struct mit Vectoren binär speichern und laden
-
Guten Tag
Ich möchte einen struct mit mehreren Vektoren in eine binäre Datei abspeichern und wider laden. Beispielsweise so etwas:
#include <stdio.h> #include <vector> using namespace std; struct Dat{ std::vector <std::string> Name; std::vector <std::string> Vorname; std::vector <std::string> Adresse; std::vector <int> PLZ; std::vector <std::string> Ort; int Zähler; } Data;
Erste Versuche auf die Art die bei mir zumindest ohne die Vektoren funktioniert hat, schlugen fehl. Es speichert irgendwie nur die PLZ ab.
#include <iostream> #include <fstream> void Write_Data() { std::fstream File; File.open("Test.dat", ios::out|ios::binary); if (File.is_open()) { File.write((const char*)&Data, sizeof(Data)); } File.close(); } void Read_Data() { fstream File("Test.dat", ios::in|ios::binary); if (File.is_open()) { while (File.read((char*)&Data, sizeof(Data))); } File.close(); }
Ich vermute mal grob, dass es irrgendwas mit dem const char* zu tun haben kann, ich hab dieses script aus irrgendeinem Forum herausgenommen, ist also nicht von mir. Ich habe bereits auf google und in eurem Forum nach einem ähnlichen Fall gesucht aber ohne Erfolg. Ich hoffe ihr könnt mir helfen, oder mir zumindest einen Link mit einer Anleitung geben.
Vielen Dank und freundliche Grüsse
Mathiable
-
Stichwort Serialisierung.
http://www.highscore.de/cpp/boost/ -> Kapitel 11
-
Lies mal die beiden Threads durch:
http://www.c-plusplus.net/forum/viewtopic-var-t-is-257297.html
http://www.c-plusplus.net/forum/viewtopic-var-t-is-252771.htmlSimon
-
Ein std::vector hält einen pointer auf daten die im heap existieren. Speicherst du eine struktur, die pointer auf daten enthält, wird auch nur gespeichert was in dem Speicherbereich existiert, den die struktur besetzt, und natürlich nicht das auf was die pointer zeigen. Du musst also über die elemente iterieren und sie einzeln abspeichern. std::string hält ebenfalls einen pointer, also musst du auch über die stringelemente iterieren.
-
Danke für die schnelle Antworten.
Michael E. schrieb:
Stichwort Serialisierung.
http://www.highscore.de/cpp/boost/ -> Kapitel 11
Ich versuche gerade noch aus der Serialisierung schlau zu werden, aber ich scheitere bereits ab dem istallieren der Boost Library. Scheint irrgendwie nicht richtig mit CodeGear zu laufen. Habe es installiert und weiss nun nicht genau was ich tun muss, damit CodeGear die Librarys erkennt. Damit wäre ich aber bereits im Falschen Forum.
Hoffe du kannst mir bald Antworten, ansosnten mache ich es wie Kontrasubjekt gesagt hat eben einzeln.
-
Auf http://www.boostpro.com/download gibts nen Installer, mit dem die Installation problemlos klappen sollte.
-
Den habe ich eben installier, ist aber für VS.
Naja, mach ich es eben einzeln...
-
Vll hilft dir das
template <class T> void PackVector(ostream* pFile, vector<T>* pData) { if (pFile && pData) for (int i = 0; i < pData->size(); i++) pFile->write((char*) pData->at(i), sizeof(T)); }
-
template <class T> void SaveVector(ostream& File, const vector<T>& Data) { File.write((char*) &Data[0], sizeof(T)*Data.size()); }
Geht natürlich nur mit eingebauten Typen.
-
Vll hilft dir das
template <class T> void PackVector(ostream* pFile, vector<T>* pData) { if (pFile && pData) { for (int i = 0; i < pData->size(); i++) pFile->write((char*) &pData->at(i), sizeof(T)); } }
-
hmmmm schrieb:
template <class T> void SaveVector(ostream& File, const vector<T>& Data) { File.write((char*) &Data[0], sizeof(T)*Data.size()); }
Geht natürlich nur mit eingebauten Typen.
Wird da alles abgespeichert oder nur das erste Element? (wegen Data[0])
-
Beliaz schrieb:
Wird da alles abgespeichert oder nur das erste Element? (wegen Data[0])
Alles:
File.write((char*) &Data[0], sizeof(T)*Data.size());
&Data[0] ist der Zeiger auf das erste Element.
-
Da er vector<string> hat reicht das nicht. Für den string braucht ihr auch noch eine Serialisierungsfunktion.
Macht mal.
-
warum eigentlich
include <stdio.h> #include <vector> struct Dat{ std::vector <std::string> Name; std::vector <std::string> Vorname; std::vector <std::string> Adresse; std::vector <int> PLZ; std::vector <std::string> Ort; int Zähler; } Data;
und nicht
include <stdio.h> #include <vector> using namespace std; struct Dat{ std::string Name; std::string Vorname; std::string Adresse; int PLZ; std::string Ort; }; typedef DatVec std::vector<Dat>; DatVec Data;
würde das nicht von der Datenbündelung her wesentlich mehr Sinn machen? Dein Zähler fällt weg, dafür gibts std::vector<Dat>::size(), zwei freie Funktionen die operator<< und >> auf Dat und DatVec für ifstream und ofstream überladen sollten dann doch genügen? Bin unsicher, habe bisher selten mit binärer speicherung gearbeitet ... Vermutlich müsstest du dann wohl sowas wie string-size,char[] wegschreiben und einlesen?
-
padreigh schrieb:
würde das nicht von der Datenbündelung her wesentlich mehr Sinn machen?
Nicht nur würde, ist definitiv sinnvoller.