Objekte auf dem Heap sichern
-
Toa schrieb:
Kann es vielleicht daran liegen das ich der FUnktion die sachen so übergeben hab :
void cWorld::status_save(sPlayer *wPlayer) <-- also das der SternOperator falsch ist ?
ja. du uebergibst einen zeiger.
mach es per referenz oder du musst den zeiger dereferenzieren.Meep Meep
-
eine dereferenzierung würde dann so ausehen sPlayer&*wPlayer; oder ? .. ach man so kurz vor dem Ziel xD
-
ne so wPlayer->money. Besser wäre es aber wenn du keinen zeiger sondern eine referenz übergen würdest. also status_save(sPlayer& wPlayer). Beim Aufrufen der funktion dann ohne & übergeben.
-
Hab jetzt zwar keine Compile errors mehr aber es geht immer noch net *heul* ich verzeifel noch xD
Meine Klasse :
class sPlayer { public: std::string name; std::string HeroTyp; int health; int mana; int maxdmg; int mindmg; int defence; int level; int xp; float geld; };Die Klasse in der die Funktionen Deffiniert sind :
class cWorld { public: // Kirche - save /Delete Account / SpielZeit anzeige void Kirche(sPlayer *wPlayer); void LoadPlayer(); void status_save(sPlayer& wPlayer); };die FUnktion in der ich die Kirche aufrufe in der man Saven kann :
void cWorld::Greenvillage(sPlayer *wPlayer) { string eingabe; // Auswahl system("cls"); getline(20); colorcout('1',"Wohin moechten Sie?"); getline(20); cout << "-Kirche\n"; newline(1); // hehe :P cin >> eingabe; ..... Bla Bla ..: else if(eingabe == "-Kirche" ||eingabe == "-Kirche" ||eingabe == "kirche" ||eingabe == "Kirche") Kirche(wPlayer); //Kirche - speichern - löschen - spielzeit { }DIe Kirche an SIch in der man speichern kann:
void cWorld::Kirche(sPlayer *wPlayer) //Kirche - speichern - löschen - spielzeit { char menue; cout << "(s)pielstand speichern\n"; cout << "(a)ccounts löschen"; cout << "(g)esamte Spielzeit anzeigen"; cout << "____________________\n"; cout << "Bitte w\204hlen:\n"; cin >> menue; cout << "\a"; switch (menue) { case ('s'): { cWorld save; save.status_save(*wPlayer); // das ist nur WIchtig !!!! }break; case ('a'): { cout << "loeschen"; }break; case ('g'): { cout << "spielzeit"; //Muss noch gemacht werden ! }break; } }Das Saven:
void cWorld::status_save(sPlayer& wPlayer) { cout << "Waehle einen Accountnamen:" << flush; // unter welchem namen soll es gespeichert werden string file_name; cin >> file_name; CreateDirectory("Saves", NULL); //legt ordner save an file_name.insert(0, "Saves\\"); if (file_name.substr(file_name.length() - 4) != ".sav") //Hängt an den namen ein Sav file_name += ".sav"; ofstream nfout(file_name.c_str(), ios::binary ); //Den inhalt des files kann ein Mensch nicht lesen, i.e. binary, not text format. nfout.write(wPlayer.name.c_str(), wPlayer.name.size() + 1); nfout.write(wPlayer.HeroTyp.c_str(), wPlayer.HeroTyp.size() + 1); //liest strings ein nfout.write(reinterpret_cast<const char*>(&(wPlayer.health)), sizeof(wPlayer.health)); //liest alles einzeln ein nfout.write(reinterpret_cast<const char*>(&(wPlayer.mana)), sizeof(wPlayer.mana)); nfout.write(reinterpret_cast<const char*>(&(wPlayer.maxdmg)), sizeof(wPlayer.maxdmg)); nfout.write(reinterpret_cast<const char*>(&(wPlayer.mindmg)), sizeof(wPlayer.mindmg)); nfout.write(reinterpret_cast<const char*>(&(wPlayer.defence)), sizeof(wPlayer.defence)); nfout.write(reinterpret_cast<const char*>(&(wPlayer.level)), sizeof(wPlayer.level)); nfout.write(reinterpret_cast<const char*>(&(wPlayer.xp)), sizeof(wPlayer.xp)); nfout.write(reinterpret_cast<const char*>(&(wPlayer.geld)), sizeof(wPlayer.geld)); nfout.close(); //schließt den Stream system("cls"); cout << "Dein Account wurde unter '" << file_name << "' gespeichert ...\n\n" ; system("pause"); }Und Später dann das laden und ausgeben :
void cWorld::LoadPlayer() { sPlayer wPlayer; string dateiname; DIR *dirHandle; // --- > liestet das verzeichniss Save auf struct dirent * dirEntry; dirHandle = opendir("Saves\\"); if (dirHandle) { while (0 != (dirEntry = readdir(dirHandle))) { puts(dirEntry->d_name); } closedir(dirHandle); } cout << "Gib den Namen deines Saves ein, den du laden willst:"; cin >> dateiname; dateiname += ".sav"; // wenn man namen ohne sav eingibt hängt das save dran system("Cls"); cout << "Load '" << dateiname << "' ...\n"; dateiname.insert(0, "Saves\\"); ifstream nfin (dateiname.c_str(), ios::binary); nfin.read(reinterpret_cast< char*>(&(wPlayer.name)), sizeof(wPlayer.name)); nfin.read(reinterpret_cast< char*>(&(wPlayer.HeroTyp)), sizeof(wPlayer.HeroTyp)); nfin.read(reinterpret_cast< char*>(&(wPlayer.health)), sizeof(wPlayer.health)); //liest alles einzeln ein nfin.read(reinterpret_cast< char*>(&(wPlayer.mana)), sizeof(wPlayer.mana)); nfin.read(reinterpret_cast< char*>(&(wPlayer.maxdmg)), sizeof(wPlayer.maxdmg)); nfin.read(reinterpret_cast< char*>(&(wPlayer.mindmg)), sizeof(wPlayer.mindmg)); nfin.read(reinterpret_cast< char*>(&(wPlayer.defence)), sizeof(wPlayer.defence)); nfin.read(reinterpret_cast< char*>(&(wPlayer.level)), sizeof(wPlayer.level)); nfin.read(reinterpret_cast< char*>(&(wPlayer.xp)), sizeof(wPlayer.xp)); nfin.read(reinterpret_cast< char*>(&(wPlayer.geld)), sizeof(wPlayer.geld)); nfin.close(); //schließt den STream cout << "Account as read from binary file " <<dateiname <<endl; system("pause"); cout << wPlayer.name << endl; system("pause"); cout << wPlayer.HeroTyp << endl; system("pause"); cout << wPlayer.health << endl; system("pause"); cout << wPlayer.mana << endl; system("pause"); cout << wPlayer.maxdmg << endl; system("pause"); cout << wPlayer.mindmg << endl; system("pause"); cout << wPlayer.defence << endl; system("pause"); cout << wPlayer.xp << endl; system("pause"); cout << wPlayer.geld << endl; system("pause"); }...SO jetzt hab ich echt alles gepostet , ich bin am rande der verzeiflung ..Seit Stunden und Tagen verusche ich es einzubaun und es geht einfach nicht
MFG TOa
-
Hallo zusammen,
bietet boost nicht Mittel zur Serialisierung?
Grüße Martin
-
http://www.boost.org/libs/serialization/doc/index.html
sollte man da einfach mal einsetzen
-
nfin.read(reinterpret_cast< char*>(&(wPlayer.name)), sizeof(wPlayer.name));So geht das nicht. Man kann nicht einfach einen std::string* nach char* casten.
Mach's z.B. so:
std::vector<char> buf(1024); nfin.read(&(buf[0]), buf.size()); wPlayer.name.assign(buf.begin(), buf.end());Damit würden allerdings nur Strings bis 1024 Zeichen eingelesen werden können, außerdem hab ich's jetzt nicht getestet.
-
Am besten schreibst du vor jeden String noch einmal die Länge des strings. Denn mein Beispiel würde jetzt nur mit Strings gehen, die immer 1024 Zeichen lang sind.
-
bitte keine tipps mehr über unsichere cast-orgien - gerade anfänger haben damit arge probleme
das boost zeug sollte wesentlich praktischer und einfacher zu verwenden sein
-
das problem beim einlesen seiner strings ist, das er nicht weiß wie lange sie sind. also koennte man beim speichern der strings noch die laenge mitgeben. dann hat man schon ein problem weniger.
inline void WriteStringToStream(std::ostream &out, const std::string &str) { std::size_t len = str.size(); out.write(reinterpret_cast<const char*>(&len), sizeof(len)); out.write(str.c_str(), len); // '\0' brauchen wir nicht mehr, weil wir die laenge speichern }zum auslesen kann man dann folgendes machen:
void ReadStringFromStream(std::istream &in, std::string &str) { std::size_t len; in.read(reinterpret_cast<char*>(&len), sizeof(len)); char *buffer = new char[len]; in.read(buffer, len); str.assign(buffer, len); delete[] buffer; }
-
schaut euch ma die ausgabe an :
http://www.imagehack.eu/uploads/b7f20d91fe.jpg
die ersten beiden Sachen stimmen noch ich hieß Ujih und mein Typ war Warrior aber die Zahlen dann nicht mehr .. also die sTrings werden richtig gespeichert und ausgegeben nur die zahlen haben Probleme
... wisst ihr warum ? die Lösung ist so nahe ^^PS :
sieht jetzt so aus :
ifstream nfin (dateiname.c_str(), ios::binary); vector<char> buf(1024); nfin.read(&(buf[0]), buf.size()); wPlayer.name.assign(buf.begin(), buf.end()); nfin.read(reinterpret_cast< char*>(&(wPlayer.HeroTyp)), sizeof(wPlayer.HeroTyp)); nfin.read(reinterpret_cast< char*>(&(wPlayer.health)), sizeof(wPlayer.health)); //liest alles einzeln ein nfin.read(reinterpret_cast< char*>(&(wPlayer.mana)), sizeof(wPlayer.mana)); nfin.read(reinterpret_cast< char*>(&(wPlayer.maxdmg)), sizeof(wPlayer.maxdmg)); nfin.read(reinterpret_cast< char*>(&(wPlayer.mindmg)), sizeof(wPlayer.mindmg)); nfin.read(reinterpret_cast< char*>(&(wPlayer.defence)), sizeof(wPlayer.defence)); nfin.read(reinterpret_cast< char*>(&(wPlayer.level)), sizeof(wPlayer.level)); nfin.read(reinterpret_cast< char*>(&(wPlayer.xp)), sizeof(wPlayer.xp)); nfin.read(reinterpret_cast< char*>(&(wPlayer.geld)), sizeof(wPlayer.geld)); nfin.close(); //schließt den STream cout << "Account as read from binary file " <<dateiname <<endl; system("pause"); cout << wPlayer.name << endl; system("pause"); cout << wPlayer.HeroTyp << endl; system("pause"); cout << wPlayer.health << endl; system("pause"); cout << wPlayer.mana << endl; system("pause"); cout << wPlayer.maxdmg << endl; system("pause"); cout << wPlayer.mindmg << endl; system("pause"); cout << wPlayer.defence << endl; system("pause"); cout << wPlayer.xp << endl; system("pause"); cout << wPlayer.geld << endl; system("pause");und noch eine Frage warum muss ich den HeroTyp denn nicht auch so wie name umschreiben und er wird trotzdem richtig ausgegeben also bzw eingelesen ...
-
Du musst noch die Größe des Strings mitspeichern. Hier mal ein Minimalbeispiel:
#include <iostream> #include <fstream> #include <vector> void SaveString(std::ofstream& fout, const std::string& str) { int size = str.size(); fout.write(reinterpret_cast<const char*>(&size), sizeof(size));S fout.write(str.c_str(), size); } std::string LoadString(std::ifstream& fin) { int size; fin.read(reinterpret_cast<char*>(&size), sizeof(size)); std::vector<char> buf(size); fin.read(&buf[0], size); std::string temp(buf.begin(), buf.end()); // oder mit .assign(...) return temp; } int main() { std::ofstream fout("test.txt"); SaveString(fout, "Hallo Welt!"); SaveString(fout, "Test!"); fout.close(); std::ifstream fin("test.txt"); std::cout << LoadString(fin) << std::endl; std::cout << LoadString(fin) << std::endl; }
-
Öhm warum denn ? die Beiden Strings werden doch richtig einglesen nur die FLoat und integer Variablen der Klasse nicht !
..meinst du dann so ?
int size = wPlayer.size();
nfout.write(reinterpret_cast<const char*>(&size), sizeof(size));Sne oder das kann net sein man muss ja irgendwo die namen der strings reinbringen aber das mit den Strings klappt ja nur wie gesagt die Interger und FLoat Variablen der Klasse sPlayer machen Probleme , sieht man ja auch auf dem Bild ..der Name und der Typ wird richtig ausgegeebn aber die Zahlen nicht die dahinter FOlgen und dann noch eine andere Frage : Ich hab doch Binary als Typ angegeben aber man kann den Namen und den Typ einfach so in der txt lesen .
-
Toa schrieb:
die Beiden Strings werden doch richtig einglesen nur die FLoat und integer Variablen der Klasse nicht !
Eigentlich wird nichts richtig gelesen. Der erste String ist 1024 Zeichen lang, mein erstes Beispiel war ziemlich schlecht. Deswegen siehst du auch noch den zweiten. Du musst die Länge irgendwie speichern, schau dir den Code von Meep Meep und mir mal an.
-
Aber es ist doch logisch das man den Zweiten auch sieht weil der ja auch ausgeeben wird .. aber ich glaube ich verstehe was du meinst wenn man nur den ersten ausgegeben h#tte , würde der zweite auch ausgegeben werden weil er mitgesavt wurde ! .. okay haste ne IDee wegen den Integer Vars und den FLoat warum die net richtig gespeichert und ausgegeebn werden ?? .. und wegen dem Lesen der txt
Kannst du mir für die beiden Strings das mit dem Länge saven mal machen ? damit ichs seh wies geht ? ...
bei saves sind es die beiden:
nfout.write(wPlayer.name.c_str(), wPlayer.name.size() + 1); nfout.write(wPlayer.HeroTyp.c_str(), wPlayer.HeroTyp.size() + 1);und bei load hab ich das
ector<char> buf(1024); nfin.read(&(buf[0]), buf.size()); wPlayer.name.assign(buf.begin(), buf.end()); nfin.read(reinterpret_cast< char*>(&(wPlayer.HeroTyp)), sizeof(wPlayer.HeroTyp));
-
gibt es eigentlich einen gund dafür das das boost zeug immer noch aktiv ignoriert wird ? (weil die cast orgien sind _____schlimm______)
-
Öhm *nachschau* ..jetzt hab ich das eine schon fast soweit nur noch das mit der char länge und den Integer und FLoat Variablen das die gehen und dann hätt ichs xD
*nach oben deut*
-
Toa schrieb:
Aber es ist doch logisch das man den Zweiten auch sieht weil der ja auch ausgeeben wird .. aber ich glaube ich verstehe was du meinst wenn man nur den ersten ausgegeben h#tte , würde der zweite auch ausgegeben werden weil er mitgesavt wurde ! .. okay haste ne IDee wegen den Integer Vars und den FLoat warum die net richtig gespeichert und ausgegeebn werden ?? .. und wegen dem Lesen der txt
Kannst du mir für die beiden Strings das mit dem Länge saven mal machen ? damit ichs seh wies geht ? ...
bei saves sind es die beiden:
nfout.write(wPlayer.name.c_str(), wPlayer.name.size() + 1); nfout.write(wPlayer.HeroTyp.c_str(), wPlayer.HeroTyp.size() + 1);und bei load hab ich das
ector<char> buf(1024); nfin.read(&(buf[0]), buf.size()); wPlayer.name.assign(buf.begin(), buf.end()); nfin.read(reinterpret_cast< char*>(&(wPlayer.HeroTyp)), sizeof(wPlayer.HeroTyp));ne, das ist ja immer noch nicht so wie wir meinten. Probier mal folgendes: Kopier dir einfach meine SaveString und LoadString funktion in dein Projekt und dann machste:
SaveString(mfout, wPlayer.name); SaveString(mfout, wPlayer.HeroTyp);und beim Laden:
wPlayer.name = LoadString(mfin); wPlayer.HeroTyp = LoadString(mfin);Achja: HeroTyp ist ein wenig komisch denn eigentlich heißt es ja type oder Held.
Und nochwas: mit [ cpp ] wird's schön bunt
-
Ohh haa jetzt mekkert er aber :
wPlayer.name = LoadString(nfin);---> invalid conversion from void to HISTANCE_*
wPlayer.name = LoadString(nfin);--->too few arguments to function int lOadStringA(HISTANCE_,UNIT CHAR int
void SaveString(std::ofstream& fout, const std::string& str)--->void saveString (SDT::ofstream& COnst Std::string&) used Prior to declaration
und warum werden die integer und Float variablen immmer noch falsch gespeichert weil er gibt ja so komische zeichen aus
und warum kann man den Namen und Typ in der txt file trotz binary lesen ?
-
Toa schrieb:
Ohh haa jetzt mekkert er aber :
wPlayer.name = LoadString(nfin);---> invalid conversion from void to HISTANCE_*
wPlayer.name = LoadString(nfin);--->too few arguments to function int lOadStringA(HISTANCE_,UNIT CHAR int
void SaveString(std::ofstream& fout, const std::string& str)--->void saveString (SDT::ofstream& COnst Std::string&) used Prior to declaration
WTF? Ich tippe mal auf WinAPI mit ihren dummen Makros, nenn die Funktion um in z.B. MyLoadString und MySaveString.
und warum werden die integer und Float variablen immmer noch falsch gespeichert weil er gibt ja so komische zeichen aus

Müsste mit dem String-Speichern zusammenhängen
und warum kann man den Namen und Typ in der txt file trotz binary lesen ?
txt-Files sind sowas wie binär files von strings. Sie sind also fast das gleiche wie wenn du Binärdateien nur mit strings beschreibst.