Save and LOad System
-
Das habsch doch schon alles, ich versuchs zu erklären was die datei macht bzw machen soll :
int health;
int mana;
int mindmg;
int maxdmg;
int defence;
char herotyp[50];
int level;
int xp;
int id=1;Das sind die sachen die Gesichert werden müssen das wird oben in der datei abgehandelt , da werden diese eigenschaften in ne Txt geschrieben.
im unterenTeil habe ich versucht ein Load QUellcode zu schreiben der diese Sachen wieder aus der txt ausliest und in variablen speichert aber es klappt nicht

-
Schön aufgelistet, die Eigenschaften. Denen gibst du jetzt vernünftige Namen und packst sie in eine Klasse.
BTW: "es klappt nicht" ist keine Fehlerbeschreibung.
-
*heul* das hab ich doch alles nur gemacht das mit dem Int war nur ein Beispiel COde damit net jeder gleich mein gesamtes game hat

struct sPlayer
{
std::string name;
std::string HeroTyp;
int health;
int mana;
int maxdmg;
int mindmg;
int defence;
int level;
int xp;
float geld;
};besser ? Ich will doch nur diese Werte in ne Txt speichern können und auch wieder laden können... ich weiß das ich es oben umständlich gemacht hab
-
Na endlich!
#include <fstream> using namespace std; int main( ) { sPlayer player; ofstream ofile( "foo.sav", ios::binary ) ofile.write( &player, sizeof( sPlayer ) ); ofile.close( ); }
-
juhu danke xD , hab das oben voll Umständlich gemacht
-
kenner der dummköpfe schrieb:
Na endlich!
#include <fstream> using namespace std; int main( ) { sPlayer player; ofstream ofile( "foo.sav", ios::binary ) ofile.write( &player, sizeof( sPlayer ) ); ofile.close( ); }Ich wage zu bezweifeln, dass ein write() mit std::strings so klappt (höchstens vielleicht ganz kurzen)....
Mein Vorschlag: Sinnvolles Protokoll definieren und damit "serialisieren" (im Javasinne).
Also sowas wie:
#include <fstream> #include <iostream> #include <string> struct sPlayer { std::string name; int health; float geld; }; std::ostream& operator<<(std::ostream& ost, sPlayer const& p) { return ost << p.name << " " << p.health << " " << p.geld << "\n"; } std::istream& operator>>(std::istream& ist, sPlayer& p) { ist >> p.name; ist >> p.health; ist >> p.geld; return ist; } using namespace std; int main( ) { sPlayer player; ofstream ofile( "foo.sav"); ofile << player; ofile.close( ); ifstream ifile( "foo.sav"); ifile >> player; return 0; }Vorteil: Egal ob File, Konsole, Netzwerk, .... mit jedem Stream funktioniert's.
Gruß,
Simon2.
-
Edit: eigener Thread dazu

http://c-plusplus.net/forum/viewtopic-var-t-is-185691.html
-
Öhm das Loaden möchte ich so machen das man sich den Account aussuchen kann, ich habe es jetzt soweit
string dateiname; DIR *dirHandle; 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; cout << "Load '" << dateiname << "' ...\n"; dateiname.insert(0, "Saves\\"); ifstream Load (dateiname.c_str(), ios::binary);ist dass richtig und wie bau ich dann da das loaden von dir ein ohne das es Probleme gibt ?
-
Toa schrieb:
...
... DIR ... struct dirent ... dirHandle = opendir(... readdir(dirHandle))) { ... closedir(dirHandle); ...Also damit bewegst Du Dich außerhalb des Standards (was nicht schlimm und vermutlich sogar notwendig ist) ... damit kenne ich mich nicht aus.
Gruß,
Simon2.
-
So fertig

#include <iostream> #include <fstream> #include <iostream> #include <string> #include <windows.h> #include <time.h> #include <sys/types.h> #include <dirent.h> using namespace std; int save(); int id_berechnen(); int load(); struct sPlayer { std::string name; std::string HeroTyp; int health; int mana; int maxdmg; int mindmg; int defence; int level; int xp; float geld; }; std::ostream& operator<<(std::ostream& ost, sPlayer const& p) { return ost << p.name << " " << p.health << " " << p.geld << " " << p.HeroTyp << " " << p.mana << " " << p.maxdmg << " " << p.mindmg << " " << p.defence << " " << p.level << " " <<p.level << " " << p.xp <<"\n"; } std::istream& operator>>(std::istream& ist, sPlayer& p) { ist >> p.name; ist >> p.health; ist >> p.geld; ist >> p.HeroTyp; ist >> p.mana; ist >> p.maxdmg; ist >> p.mindmg; ist >> p.defence; ist >> p.level; ist >> p.xp; return ist; } int id_berechnen() // Ganz WIchtig es muss einen ordner ID mit einer id.txt geben wo eine 0 drin steht !!!!!! { ifstream file("ID\\id.txt"); char line[100]; file.get( line, 100); file.close(); int value; value = atoi( line ); value += 1; ofstream out ( "ID\\id.txt" ); out << value; out.close(); return value; } int save() { int berechnete_id=id_berechnen(); cout << "Waehle einen Accountnamen:" << flush; string file_name; getline(cin, file_name); CreateDirectory("Saves", NULL); file_name.insert(0, "Saves\\"); if (file_name.substr(file_name.length() - 4) != ".sav") file_name += ".sav"; sPlayer player; ofstream ofile(file_name.c_str(), ios::app); ofile << berechnete_id; ofile << endl; ofile << player; cout << "Dein Account wird unter '" << file_name << "' gespeichert ..." << "\n"<< endl; system("pause"); system("cls"); ofile.close(); } int load() { string dateiname; DIR *dirHandle; 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; cout << "Load '" << dateiname << "' ...\n"; dateiname.insert(0, "Saves\\"); sPlayer player; ifstream Load (dateiname.c_str(), ios::binary); Load >> player; Load.close(); }Glaubst du das klappt so , weil wenn ich das Compilier kommt :
C:\Programme\CodeBlocks\lib\libmingw32.a(main.o):main.c:(.text+0x106): undefined reference to `WinMain@16'
collect2: ld returned 1 exit status
Process terminated with status 1 (0 minutes, 3 seconds)mh... und so kann ich die daten aus der Struktur in die Txt packen und wenn ich dann auf LOad zugreif sind sie wieder so in der Struktur geladen ?
Edit :
Ist es Besser wenn ich es so schreibe ?
int Laden() { // Datei zum Lesen öffnen und Spielestand laden cout << "\nLade Charakter...\n"; ifstream Load (".", ios::binary); Load.read ((char*) &wPlayer.Abenteuerpunkte, sizeof (wPlayer.Abenteuerpunkte)); Load.read ((char*) &wPlayer.name, sizeof (wPlayer.name)); Load.read ((char*) &wPlayer.HeroTyp, sizeof (wPlayer.HeroTyp)); Load.read ((char*) &wPlayer.health, sizeof (wPlayer.health)); Load.read ((char*) &wPlayer.mana, sizeof (wPlayer.mana)); Load.read ((char*) &wPlayer.maxdmg, sizeof (wPlayer.maxdmg)); Load.read ((char*) &wPlayer.mindmg, sizeof (wPlayer.mindmg)); Load.read ((char*) &wPlayer.defence, sizeof (wPlayer.defence)); Load.read ((char*) &wPlayer.level, sizeof (wPlayer.level)); Load.read ((char*) &wPlayer.xp, sizeof (wPlayer.xp)); Load.read ((char*) &wPlayer.geld, sizeof (wPlayer.geld)); // Datei schließen Load.close (); return true; } int Speichern() { // Datei zum Schreiben öffnen cout << "\nSpeicher Charakter...\n"; ofstream Save("", ios::binary); Save.write ((char*) &wPlayer.name, sizeof (wPlayer.name)); Save.write ((char*) &wPlayer.HeroTyp, sizeof (wPlayer.HeroTyp)); Save.write ((char*) &wPlayer.health, sizeof (wPlayer.health)); Save.write ((char*) &wPlayer.mana, sizeof (wPlayer.mana)); Save.write ((char*) &wPlayer.maxdmg, sizeof (wPlayer.maxdmg)); Save.write ((char*) &wPlayer.mindmg, sizeof (wPlayer.mindmg)); Save.write ((char*) &wPlayer.defence, sizeof (wPlayer.defence)); Save.write ((char*) &wPlayer.level, sizeof (wPlayer.level)); Save.write ((char*) &wPlayer.xp, sizeof (wPlayer.xp)); Save.write ((char*) &wPlayer.geld, sizeof (wPlayer.geld)); // Datei schließen Save.close (); }
-
Toa schrieb:
...
Glaubst du das klappt so , weil wenn ich das Compilier kommt :...Kleiner Tipp: Schreibe nicht so, wie Du sprichst ! Denke daran, dass ich keine Betonungen mithöre.
Ich brauchte 3 Anläufe, bis ich verstanden hab, was Du damit meinst. Du klebst ier zwei Sätze zu einem zusammen, sparst ein Fragezeichen (dauerte schon, bis ich begriff, dass Du hier eine Frage stellst) und einen Halbsatz "Ich bin mir nicht sicher, ...".OK, zum Thema: Dein "Compiler" (genauergesagt: Der Teil, der "Linker" genannt wird) will wissen, wo Dein Programm anfangen soll und erwartet deswegen eine "WinMain"-Funktion. Ist wieder windowsspezifisch (der Standard hat dafür die Funktion main()), weswegen ich Dir nicht genau sagen kann, wie Du das machst. Schau Dir einfach nochmal die Beispiele bei Deiner Entwicklungsumgebung (oder hier im Windows-unterforum) an.
Toa schrieb:
...
Ist es Besser wenn ich es so schreibe ?
...Kurz gesagt: Nein !
Hier schreibst Du "direkt binär" aus dem Speicher ins File. Was erstmal gut klingt, geht bei komplexeren Datentypen (wie z.B. std::string) schnell in die Hose, weil die selbst Daten "auslagern" und organisieren. Diese "ausgelagerten Daten" erwischt man dann nicht mit. Besser ist es, jeden Datentypen selbst seine "Serialisierung" (sprich: Die Form, in der er abgelegt werden möchte) bestimmen zu lassen und das machen die operator<<() und ..>>() für viele Typen schon gut und korrekt.Gruß,
Simon2.
-
OKay habe ich soweit verstanden.Habe alles jetzt in eine Klasse geschrieben und ich denke es müsste klappen. Will mich noch mal bei dir bedanken und an meiner Forenschreibweiße werde ich arbeiten .
MFG Toa