struct speichern/laden ->Fehler!
-
Also ich habe: #include "fstream.h" inkludiert.
Mir wäre lieber wenn der operator auch binär schreiben würde.
In meinem Prog. ist info ein Pointer, da es ein Array ist. (von struct Info)
-
Wenn es ein Pointer ist, mußt du dereferenzieren. Wenn es aber ein Array ist, kannst du ja auch mit [] auf das zu schreibende Element zugreifen.
Vielleicht solltest du uns den korrekten Code zeigen wo der Fehler auftritt.So wie dein operator<< aufgebaut ist schreibt er nicht binär, sondern im Textmodus. Das ist hier auch notwendig, um das Ende der Strings ordentlich zu kennzeichnen.
Wenn du binär schreiben willst solltest du deiner struct die memberfunktionen read/write spendiern, die das dann übernehmen. Bei Streams sind die nämlich für binäre daten zuständig. Wenn du Strings binär schreiben willst, solltest du immer vorher die Länge mit abspeicher, damit du wieder ordentlich einlesen kannst.fstream.h ist sowieso falsch. Wenn schon, dann #include <fstream>.
das meinte ich hier aber gar nicht. Ich meinte den header, wo deine Operatoren<< und >> deklariert worden sind.
-
Also ich hatte mir vorgestellt es wie in java zu machen.
Aber nun gut,
Wenn du binär schreiben willst solltest du deiner struct die memberfunktionen read/write spendiern, die das dann übernehmen. Bei Streams sind die nämlich für binäre daten zuständig.
Wie sähen die Memberfunktionen aus?
fstream.h ist sowieso falsch. Wenn schon, dann #include <fstream>
Was ist der unterschied?
Ich meinte den header, wo deine Operatoren<< und >> deklariert worden sind.
Imo sind die mit in der cpp Datei, "Unit.cpp".
Die Stelle des Fehlers ist:(Zeile 18)
int Unit::loadInfoFromFile(char *datei) { //----Stream-initialisieren---- ifstream ifl(datei, ios::in|ios::binary); //----Fehler?---- if(!ifl) { return 0; } //----Länge-bestimmen---- unsigned int ende; ifl.seekg(0, ios::end); ende = ifl.tellg(); ifl.seekg(0, ios::beg); //----Daten-einlesen---- //info = new Info[ende/sizeof(Info)]; //ifl.read((char*)info, ende); ifl >> info; //----Stream-schließen---- ifl.close(); //----Alles-OK---- return 1; }
-
Hallo
Wie sähen die Memberfunktionen aus?
Da must du dir schon selber einen Kopf machen. Da du ja mit den AnsiStrings keine reine PODs mehr hast gibt es kein einfaches binäres Format mehr.
Was ist der unterschied?
Braunsteins Verbesserung zeigt den aktuellen C++ Standard
Imo sind die mit in der cpp Datei, "Unit.cpp".
Vermutlich aber erst nachdem Aufruf in loadInfoFromFile?
Du must die Op-Deklaration (und nur die Deklaration, nicht die Implementatio) auch in die Unit.h schreiben.bis bald
akari
-
Dragonfire schrieb:
Wie sähen die Memberfunktionen aus?
so etwa
ostream& Info::write(ostream& out) const { int strsize = spiel.Length(); out.write(reinterpret_cast<const char*>(&strsize), sizeof(strsize)); out.write(spiel().c_str(), strsize+1); // usw. } istream& Info::read(istream& in) { int strsize; in.read(reinterpret_cast<char*>(&strsize), sizeof(strsize)); char* tstr = new char[strsize+1]; in.read(tstr, strsize+1); delete[] tstr; // usw.
-
Da must du dir schon selber einen Kopf machen. Da du ja mit den AnsiStrings keine reine PODs mehr hast gibt es kein einfaches binäres Format mehr.
Die AnsiString müssen nicht sein, man kann ja auch char[] verwenden, nötigenfalls mit begrenzung, z.B. char[255].
Braunsteins Verbesserung zeigt den aktuellen C++ Standard
Aha

Du must die Op-Deklaration (und nur die Deklaration, nicht die Implementatio) auch in die Unit.h schreiben.
Hab ich gemacht (ich dummi^^).
Nun bekomm ich folgende Meldung:[C++ Fehler] CraGine.h(42): E2080 'Unit::operator <<(ostream,const Info)' muß mit einem Parameter deklariert werden
thx nochmal für die Mühen

[EDIT]Oh zuspät...Danke
, ich probiers gleich mal aus.[/EDIT]
-
Die Deklaration sollte so aussehen
std::ostream& operator<<(std::ostream& stream, const Info& info);Natürlich muß Info zu diesem Zeitpunkt bekannt sein. Es ist sowieso am besten die Operation im selben headerfile wie die Klasse zu deklarieren.
-
so bin jetzt soweit:
#unit.cpp#
... ostream& Info::write(ostream& out) const { int strsize = spiel.Length(); out.write(reinterpret_cast<const char*>(&strsize), sizeof(strsize)); out.write(spiel().c_str(), strsize+1); strsize = version.Length(); out.write(reinterpret_cast<const char*>(&strsize), sizeof(strsize)); out.write(version().c_str(), strsize+1); strsize = typ.Length(); out.write(reinterpret_cast<const char*>(&strsize), sizeof(strsize)); out.write(typ().c_str(), strsize+1); strsize = autor.Length(); out.write(reinterpret_cast<const char*>(&strsize), sizeof(strsize)); out.write(autor().c_str(), strsize+1); strsize = beschreibung.Length(); out.write(reinterpret_cast<const char*>(&strsize), sizeof(strsize)); out.write(beschreibung().c_str(), strsize+1); strsize = erweiterung.Length(); out.write(reinterpret_cast<const char*>(&strsize), sizeof(strsize)); out.write(erweiterung().c_str(), strsize+1); strsize = sizeof(groesse); out.write(reinterpret_cast<const char*>(&strsize), sizeof(strsize)); out.write(groesse, strsize+1); }Bei:
istream& Info::read(istream& in) { int strsize; in.read(reinterpret_cast<char*>(&strsize), sizeof(strsize)); char* tstr = new char[strsize+1]; in.read(tstr, strsize+1); delete[] tstr; // usw. }Was bedeutet/was ist hier: tstr?
#unit.h#
... ostream& write(ostream&) const; istream& read(istream&);trotzdem kennt er die Methoden in der cpp datei nicht...
-
tstr ist nur ein temporärer String. Ich hatte da vergessen den eingelesenen Inhalt zu übertragen.
So wäre es richtig.istream& Info::read(istream& in) { int strsize; in.read(reinterpret_cast<char*>(&strsize), sizeof(strsize)); char* tstr = new char[strsize+1]; in.read(tstr, strsize+1); spiel = tstr; delete[] tstr; // usw. }Beim write oben müssen die Klammern nach spiel usw. weg. (auch mein Fehler).
Die Deklarationen von read und write gehören in deine Info-Klasse.
Bitte versuche mal zu verstehen was das bedeutet. Dann mußt du auch nicht mehr so viel fragen und findest deartige Fehler selber.
-
Gut
Mach ich.Nur bin ich im speichern auf Festplatte in C++ nicht so fit^^.
Nur habe ich immer noch die Fehlermeldung:
[C++ Fehler] Unit.cpp(222): E2015 Mehrdeutigkeit zwischen '_STL::basic_istream<char,_STL::char_traits<char> >::operator >>(bool &)' und '_STL::basic_istream<char,_STL::char_traits<char> >::operator >>(void * &)'
-
Poste mal den relevanten Code. Du willst anscheinend immer noch einen Zeiger auf Info ausgeben.
Lies dir evtl. noch das hier aus der C++ FAQ durch
Ströme und Dateien in C++
-
Gut:
Unit.h:
//--------------------------------------------------------------------------- #ifndef UnitH #define UnitH #include <fstream> #include <system> //--------------------------------------------------------------------------- struct Info { AnsiString spiel; AnsiString version; AnsiString typ; AnsiString autor; int groesse; AnsiString beschreibung; AnsiString erweiterung; ostream& write(ostream&) const; istream& read(istream&); }; class Loesung { private: char *datei; Info *info; AnsiString version; void extendInfoArray(); void reduceInfoArray(); int loesungen; int getInfoArrayLength(); public: Loesung(); ~Loesung(); int einlesen(char*); int speichern(char*); Info getInfos(int); AnsiString getVersion(); void verifizieren(AnsiString, AnsiString, AnsiString, AnsiString, AnsiString); int getLoesungAnzahl(); int saveInfoToFile(char*); int loadInfoFromFile(char*); int loadLoesungFromArchive(char*,int); AnsiString test(); }; //--------------------------------------------------------------------------- #endifUnit.cpp:
//--------------------------------------------------------------------------- #pragma hdrstop #include <Unit> //--------------------------------------------------------------------------- #pragma package(smart_init) //--------------------------------------------------------------------------- Loesung::Loesung() { version = "0.4.9"; info = new Info[1]; loesungen = 0; } //--------------------------------------------------------------------------- //Gibt 0 zurück wenn ein Fehler auftrat, 1 wenn nicht int Loesung::einlesen(char *datei) { //----Stream-initialisieren---- ifstream ifl(datei, ios::in|ios::binary); //----Fehler?---- if(!ifl) { return 0; } //----Länge-bestimmen---- unsigned int ende; ifl.seekg(0, ios::end); ende = ifl.tellg(); ifl.seekg(0, ios::beg); //----Array-initialisieren---- delete datei; datei = new char[ende]; //----Daten-einlesen---- ifl.read((char*)datei, ende); //----Stream-schließen---- ifl.close(); //----Info-vorbereiten---- if(loesungen > 0) { extendInfoArray(); } //----Info-setzen---- info[loesungen].groesse = ende; AnsiString erw = (AnsiString)datei; int punkt = erw.LastDelimiter("."); erw = erw.SubString(punkt, erw.Length()-punkt); info[loesungen].erweiterung = erw.c_str(); //----Alles-OK---- return 1; } //--------------------------------------------------------------------------- //Gibt 0 zurück wenn ein Fehler auftrat, 1 wenn nicht int Loesung::speichern(char *datei) { //----Stream-initialisieren---- ofstream ofl(datei, ios::out|ios::binary); //----Fehler?---- if(!ofl) { return 0; } //----Zeiger-auf-das-Ende-richten-zum-anhängen---- ofl.seekp(0, ios::end); //----Schreiben---- ofl.write((char*)datei, info[loesungen].groesse); //----Stream-schließen---- ofl.close(); //----Eine-Loesung-mehr---- loesungen ++; //----Alles-OK---- return 1; } //--------------------------------------------------------------------------- Info Loesung::getInfos(int n) { return info[n]; } //--------------------------------------------------------------------------- AnsiString Loesung::getVersion() { return version; } //--------------------------------------------------------------------------- void Loesung::verifizieren(AnsiString sp, AnsiString ve, AnsiString ty, AnsiString au, AnsiString be) { info[loesungen].spiel = sp.c_str(); info[loesungen].version = ve.c_str(); info[loesungen].typ = ty.c_str(); info[loesungen].autor = au.c_str(); info[loesungen].beschreibung = be.c_str(); } //--------------------------------------------------------------------------- Loesung::~Loesung() { } //--------------------------------------------------------------------------- int Loesung::getLoesungAnzahl() { return loesungen; } //--------------------------------------------------------------------------- void Loesung::extendInfoArray() { if(loesungen == 0) { return; } Info *dummy = new Info[loesungen+1]; for(int i; i < loesungen; i ++) { dummy[i].spiel = info[i].spiel; dummy[i].version = info[i].version; dummy[i].typ = info[i].typ; dummy[i].autor = info[i].autor; dummy[i].groesse = info[i].groesse; dummy[i].beschreibung = info[i].beschreibung; dummy[i].erweiterung = info[i].erweiterung; } info = new Info[loesungen+1]; for(int i; i < loesungen; i ++) { info[i].spiel = dummy[i].spiel; info[i].version = dummy[i].version; info[i].typ = dummy[i].typ; info[i].autor = dummy[i].autor; info[i].groesse = dummy[i].groesse; info[i].beschreibung = dummy[i].beschreibung; info[i].erweiterung = dummy[i].erweiterung; } } //--------------------------------------------------------------------------- void Loesung::reduceInfoArray() { if(loesungen == 0) { return; } Info *dummy = new Info[loesungen-1]; for(int i; i < loesungen; i ++) { dummy[i].spiel = info[i].spiel; dummy[i].version = info[i].version; dummy[i].typ = info[i].typ; dummy[i].autor = info[i].autor; dummy[i].groesse = info[i].groesse; dummy[i].beschreibung = info[i].beschreibung; } info = new Info[loesungen-1]; for(int i; i < loesungen; i ++) { info[i].spiel = dummy[i].spiel; info[i].version = dummy[i].version; info[i].typ = dummy[i].typ; info[i].autor = dummy[i].autor; info[i].groesse = dummy[i].groesse; info[i].beschreibung = dummy[i].beschreibung; } loesungen --; } //--------------------------------------------------------------------------- int Loesung::saveInfoToFile(char *datei) { //----Stream-initialisieren---- ofstream ofl(datei, ios::out|ios::binary); //----Fehler?---- if(!ofl) { return 0; } //----Schreiben---- //ofl.write((char*)info, sizeof(*info)); ofl << info; //----Stream-schließen---- ofl.close(); //----Alles-OK---- return 1; } //--------------------------------------------------------------------------- int Loesung::loadInfoFromFile(char *datei) { //----Stream-initialisieren---- ifstream ifl(datei, ios::in|ios::binary); //----Fehler?---- if(!ifl) { return 0; } //----Länge-bestimmen---- unsigned int ende; ifl.seekg(0, ios::end); ende = ifl.tellg(); ifl.seekg(0, ios::beg); //----Daten-einlesen---- //info = new Info[ende/sizeof(Info)]; //ifl.read((char*)info, ende); ifl >> info; //----Stream-schließen---- ifl.close(); //----Loesungen-setzen---- loesungen = getInfoArrayLength(); //----Alles-OK---- return 1; } //--------------------------------------------------------------------------- int Loesung::loadLoesungFromArchive(char *datei, int n) { int gr = 0; for(int i = 0; i < n-1; i ++) { gr += info[i].groesse; } //----Stream-initialisieren---- ifstream ifl(datei, ios::in|ios::binary); //----Fehler?---- if(!ifl) { return 0; } //----Länge-bestimmen---- unsigned int ende; ifl.seekg(0, ios::end); ende = ifl.tellg(); ifl.seekg(0, gr); //----Array-initialisieren---- delete datei; datei = new char[ende-gr]; //----Daten-einlesen---- ifl.read((char*)datei, ende-gr); //----Stream-schließen---- ifl.close(); //----Alles-OK---- return 1; } //--------------------------------------------------------------------------- int Loesung::getInfoArrayLength() { return sizeof(*info)/sizeof(Info); } //--------------------------------------------------------------------------- AnsiString Loesung::test() { } //--------------------------------------------------------------------------- istream& read(istream& in) { int strsize; in.read(reinterpret_cast<char*>(&strsize), sizeof(strsize)); char* tstr = new char[strsize+1]; in.read(tstr, strsize+1); spiel = tstr; delete[] tstr; strsize; in.read(reinterpret_cast<char*>(&strsize), sizeof(strsize)); tstr = new char[strsize+1]; in.read(tstr, strsize+1); version = tstr; delete[] tstr; strsize; in.read(reinterpret_cast<char*>(&strsize), sizeof(strsize)); tstr = new char[strsize+1]; in.read(tstr, strsize+1); typ = tstr; delete[] tstr; strsize; in.read(reinterpret_cast<char*>(&strsize), sizeof(strsize)); tstr = new char[strsize+1]; in.read(tstr, strsize+1); autor = tstr; delete[] tstr; strsize; in.read(reinterpret_cast<char*>(&strsize), sizeof(strsize)); tstr = new char[strsize+1]; in.read(tstr, strsize+1); beschreibung = tstr; delete[] tstr; strsize; in.read(reinterpret_cast<char*>(&strsize), sizeof(strsize)); tstr = new char[strsize+1]; in.read(tstr, strsize+1); erweiterung = tstr; delete[] tstr; strsize; in.read(reinterpret_cast<char*>(&strsize), sizeof(strsize)); int val; in.read((char*)val, strsize+1); groesse = val; } //--------------------------------------------------------------------------- ostream& write(ostream& out) const { int strsize = spiel.Length(); out.write(reinterpret_cast<const char*>(&strsize), sizeof(strsize)); out.write(spiel.c_str(), strsize+1); strsize = version.Length(); out.write(reinterpret_cast<const char*>(&strsize), sizeof(strsize)); out.write(version.c_str(), strsize+1); strsize = typ.Length(); out.write(reinterpret_cast<const char*>(&strsize), sizeof(strsize)); out.write(typ.c_str(), strsize+1); strsize = autor.Length(); out.write(reinterpret_cast<const char*>(&strsize), sizeof(strsize)); out.write(autor.c_str(), strsize+1); strsize = beschreibung.Length(); out.write(reinterpret_cast<const char*>(&strsize), sizeof(strsize)); out.write(beschreibung.c_str(), strsize+1); strsize = erweiterung.Length(); out.write(reinterpret_cast<const char*>(&strsize), sizeof(strsize)); out.write(erweiterung.c_str(), strsize+1); strsize = sizeof(groesse); out.write(reinterpret_cast<const char*>(&strsize), sizeof(strsize)); out.write(groesse, strsize+1); } //---------------------------------------------------------------------------
-
Ok,
mach mal aus #include <Unit> besser #include "Unit.h"
Du sollst das .h nicht bei allen Include weglassen sondern nur bei den Standardheadern (system ist auch kein Standardheader).2. Deklaration der Schreib/Lesefunktionen sollte so aussehen
std::ostream& write(std::ostream&) const; std::istream& read(std::istream&);Du mußt den namespace std in den Headerdateien immer mit angeben.
3. Bei den Definitionen dieser Funktionen hast du den Klassenscope vergessen.
alsoistream& Info::read(istream& in)4. saveInfoToFile ist falsch
so wird es besserbool Loesung::saveInfoToFile(char *datei) { //----Stream-initialisieren---- ofstream ofl(datei, ios::out|ios::binary); //----Fehler?---- if(!ofl) return false; //----Schreiben---- info[loesungen].write(ofl); // write ist doch eine Memberfunktion von Info return true; }5. das hier funktioniert nicht
int Loesung::getInfoArrayLength() { return sizeof(*info)/sizeof(Info); }Merke dir lieber die Größe deines Arrays in einer membervariablen von Loesung und gib die dann zurück.
6. Was sollen in verifizieren die vielen c_str()?
7. Überarbeite einlesen noch mal. da ist vieles faul drin. Warum übergibst du den Dateinamen als char* ? Nimm lieber überall AnsiString.
8. Weiter habe ich jetzt nicht geschaut, da ich jetzt langsam Feierabend machen werde.
Ciao
-
so habs geschafft, Danke!
