Programmeinstellungen speichern (strukt,klasse, welche methoden/funktionen)
-
Hallo,
also die letzten programme die ich geschrieben habe, hatten schon immer ein paar
einstellmöglickeiten. Ich sag jetzt mal, dass ich so ca. 10 bis 20 variablen
hatte die ich speichern musste. Das sind dann Strings, ints und bools etc... Es
könnte halt alles sein. Wie würdet ihr sowas jetzt handhaben. Angenommen ihr
habt ein FTP-Client geschrieben und möchtet die Daten der letzten Sitzung
speichern. Mit Handhaben mein ich jetzt nicht nur die Speicherung auf dem
Datenträger, sondern auch die speicherung im speicher.
Also wenn man z.b. sowas hätte://Ftp Server Daten AnsiString Username; AnsiString Password; AnsiString Ip; short port bool Ascii; //Programmeneinstellungen bool Vollbildmodus; bool AutoConnect; bool AutoSave;Wie programmiert ihr das jetzt?
-
Also so könnte man das doch lösen, oder wäre euch das zu "aufwändig"?
//struct zur übersichtlichkeit? struct TFtpServer { AnsiString Username; AnsiString Password; AnsiString Ip; short port bool Ascii; } // Klasse zum verwalten der optionen. class TOptionen { private: public: //Ftp Server Daten TFtpServer FtpServer; //Programmeneinstellungen bool Vollbildmodus; bool AutoConnect; bool AutoSave; /* Methoden */ void SaveToIni(); bool LoadFromIni(); }; bool TOptionen::LoadFromIni() { if( !FileExists( ChangeFileExt( Application->ExeName, ".INI") ) { return false; } else { TIniFile *ini; ini = new TIniFile( ChangeFileExt( Application->ExeName, ".INI") ); //FtpServerDaten ini->ReadString( "FtpServerDaten", "Username", ""); ini->ReadString( "FtpServerDaten", "Password", ""); ini->ReadString( "FtpServerDaten", "Ip", ""); ini->ReadInteger( "FtpServerDaten", "Port", 21); ini->ReadBool( "FtpServerDaten", "Ascii", true); //Programmeinstellungen ini->ReadBool( "Programmeinstellungen", "Vollbildmodus", true); ini->ReadBool( "Programmeinstellungen", "AutoConnect", true); ini->ReadBool( "Programmeinstellungen", "AutoSave", true); delete ini; } return true; } void TOptionen::SaveToIni() { TIniFile *ini; ini = new TIniFile( ChangeFileExt( Application->ExeName, ".INI") ); //FtpServerDaten ini->WriteString( "FtpServerDaten", "Username", this->FtpServer.Username); ini->WriteString( "FtpServerDaten", "Password", this->FtpServer.Password); ini->WriteString( "FtpServerDaten", "Ip", this->FtpServer.Ip; ini->WriteInteger( "FtpServerDaten", "Port", this->FtpServer.port); ini->WriteBool( "FtpServerDaten", "Ascii", this->FtpServer.Ascii); //Programmeinstellungen ini->WriteBool( "Programmeinstellungen", "Vollbildmodus", this->Vollbildmodus); ini->WriteBool( "Programmeinstellungen", "AutoConnect", this->AutoConnect); ini->WriteBool( "Programmeinstellungen", "AutoSave", this->AutoSave); delete ini; }
-
Andere möglichkeit wäre noch diese hier:
//struct zur übersichtlichkeit? struct TFtpServer { AnsiString Username; AnsiString Password; AnsiString Ip; short port bool Ascii; } // Klasse zum verwalten der optionen. class TOptionen { private: public: //Ftp Server Daten TFtpServer FtpServer; //Programmeneinstellungen bool Vollbildmodus; bool AutoConnect; bool AutoSave; /* Methoden */ bool SaveToFile(); bool LoadFromFile(); }; bool TOptionen::LoadFromFile() { if( !FileExists( ChangeFileExt( Application->ExeName, ".dat") ) { return false; } else { fstream Datei; if( Datei.open( ChangeFileExt( Application->ExeName, ".dat"), ios::in | ios::binary ) ) { Datei.read( (char*)this, ( sizeof(this) ); Datei.close(); } else { return false; } } return true; } bool TOptionen::SaveToFile() { fstream Datei; if( Datei.open( ChangeFileExt( Application->ExeName, ".dat"), ios::out | ios::binary ) ) { Datei.write( (char*)this, ( sizeof(this) ); Datei.close(); return true; } else { return false; } }Allerdings bekomme ich hier den huddel, dass ich probleme mit den, in der
größe dynamischen, attributen bekomme. Ich muss ja dann vorher noch die
ansistrings in char arrays mit fixer länger schreiben, dort zwischen speichern
und dann erst auf den datenträger schreiben.
Ich weiß auch gerade gar nicht ob das mit demDatei.write( char*)this, ( sizeof(this) );so einfach geht. Ich hab das sonst mit structs und nicht mit klassen gemacht.
-
Filestreams kommen für sowas auch nicht in Frage oder?
Gibt es denn irgendwas, das mit den AnsiStrings so fertig wird, außer die ini files?
-
Hallo
TFileStreams können schon mit AnsiStrings umgehen, die std::fstreams mit einem Trick auch.
Aber was gefällt dir an TIniFile nicht? Das scheint genau das richtige für deinen Zweck zu sein.
bis bald
akari
-
Probleme kommen auf, wenn man jetzt z.b. ein Array speichern will.
struct TFtpServer { AnsiString Username; AnsiString Password; AnsiString Ip; short port bool Ascii; } // Klasse zum verwalten der optionen. class TOptionen { private: public: //Ftp Server Daten TFtpServer FtpServerListe[20]; /* Hier würd ich z.b. gerne 20 Server speichern. */ /* ... */ void SaveToIni(); bool LoadFromIni(); };Wie würdest du das jetzt speichern? Ne Zählschlafe in der SaveToIni() und
LoadFromIni() die dann so irgendwie aussieht:TOptionen::SaveToIni() { /* ... */ for(int i=0; i < 20; i++) { ini->WriteString( "FtpServer" + IntToStr(i), "Username", this->FtpServer[i].Username); ini->WriteString( "FtpServer" + IntToStr(i), "Password", this->FtpServer[i].Password); ini->WriteString( "FtpServer" + IntToStr(i), "Ip", this->FtpServer[i].Ip; ini->WriteInteger( "FtpServer" + IntToStr(i), "Port", this->FtpServer[i].port); ini->WriteBool( "FtpServer" + IntToStr(i), "Ascii", this->FtpServer[i].Ascii); } /* ... */ }Oder gibts da was eleganteres?
Wäre auch dankbar, wenn du mir mal den Trick verraten würdest, wie ich mit
einem fstream einen AnsiString laden und speichern kann ohne in ihn einen fixen
char zu packen.danke

-
Weiß nicht was an der Lösung für ein Array jetzt so unelegant wäre.
Das ist so ziemlich das Beste was du machen kannst.
Allerdings würde ich einen Wert in der ini abspeichern der vielleicht max_count heißt und die Anzahl der Array-Elemente enthält.
Das wäre dann wirklich elegant gelöst