exception bei string = string warum????
-
Decimad schrieb:
Schließlich kann man doch auch const-Referenzen so übergeben, wenn ich mich recht entsinne?
Jein. Der einzige trick, ein temporäres Objekt etwas länger am Leben zu halten ist, es an eine const Referenz zu binden:
Foo bar(); Foo const& f = bar(); //das temporäre Ergebnis von bar wird an f gebunden Foo & f2 = bar(); //undefiniert, da f2 keine const Referenz ist.
-
pumuckl schrieb:
Foo f2 = bar(); //undefiniert, da f2 keine const Referenz ist.Da fehlt ein '&'.
-
jup, danke, erledigt

-
Erstmal vielen dank für alle eure Verbesserungsvorschläge!!!
Ich habe den Code etwas verändert, und der Fehler ist weg, das einzige was ich gemacht habe war dass ich die save und load funktion verändert habe und der fehler ist weg...
also das war ein sehr seltsamer fehler.
Leider bleibt ein Fehler: Wenn ich einen Key eingebe und speichere, dann das Prog neu starte, dann ist der Key weg, also wurde er nicht gespeichert... warum????
hier nochmal der aktuelle code:
Key.h:
#ifndef KEY #define KEY #include <string> #include <fstream> class Key { public: Key() {Delete();} Key(std::string const& sName, std::string const& sKey) : m_bExist(false), m_sName(sName), m_sKey(sKey) {} ~Key() {} void Delete(); void SetName(std::string const& sName = ""); void SetKey(std::string const& sKey = ""); std::string GetName() const; std::string GetKey() const; bool IsName(std::string const&); bool IsKey(std::string const&); bool Save(std::string const& sFile = "Keys.dat"); bool Load(std::string const& sFile = "Keys.dat"); operator bool(); private: void readstring_binary(std::istream&,std::string); void writestring_binary(std::ostream&,std::string); bool m_bExist; std::string m_sName; std::string m_sKey; }; #endifKey.cpp
#include "key.h" using namespace std; void Key::Delete() { m_bExist = false; m_sName = ""; m_sKey = ""; } void Key::SetName(string const& sName) { m_bExist = true; m_sName = sName; } void Key::SetKey(string const& sKey) { m_bExist = true; m_sKey = sKey; } string Key::GetName() const { return m_sName; } string Key::GetKey() const { return m_sKey; } bool Key::IsName(string const& sName) { return m_sName == sName; } bool Key::IsKey(string const& sKey) { return m_sKey == sKey; } bool Key::Save(string const& sFile) { bool bGood; ofstream ofDatei(sFile.c_str(), ios::binary | ios::trunc); ofDatei.write((char *) &m_bExist, sizeof(bool)); writestring_binary(ofDatei, m_sName); writestring_binary(ofDatei, m_sKey); bGood = ofDatei.good(); ofDatei.close(); ofDatei.clear(); return bGood; } bool Key::Load(string const& sFile) { bool bGood; ifstream ifDatei(sFile.c_str(), ios::binary); ifDatei.read((char *) &m_bExist, sizeof(bool)); readstring_binary(ifDatei, m_sName); readstring_binary(ifDatei, m_sKey); bGood = ifDatei.good(); ifDatei.close(); ifDatei.clear(); return bGood; } Key::operator bool() { return m_bExist; } void Key::writestring_binary( std::ostream& o, std::string str ) { std::size_t temp = str.size(); o.write( (const char*) &temp, sizeof( std::size_t ) ); o.write( str.data(), str.size() ); } void Key::readstring_binary( std::istream& i, std::string str ) { std::size_t s; i.read( (char*)&s, sizeof( std::size_t ) ); str.clear(); str.reserve( s ); char c; for( std::size_t n = 0; n < s; ++n ) { i.get( c ); str += c; } }und die funktion, die ich zum speichern/laden aufrufe + die relewanten deklarationen
// Globale variablen Key g_Keys[MAX_KEYS]; // MAX_KEYS ist zur zeit 126 // die funktionen int load() { for(int i = 0; i < MAX_KEYS; i++) { if(!g_Keys[i].Load("data\\Keys.dat")) return ERROR_READ; } return OK; } int save() { for(int i = 0; i < MAX_KEYS; i++) { if(!g_Keys[i].Save("data\\Keys.dat")) return ERROR_WRITE; } return OK; }achja und ne kleine frage am rande was ist foo und was ist bar über das ihr hier redet?
-
Yazoo schrieb:
also das war ein sehr seltsamer fehler.
Eigentlich nicht. Ein std::string allokiert dynamisch Speicher für die Zeichenkette, die er repräsentiert. Wenn du nur das Objekt selbst so wie gehabt in seiner Binärdarstellung in eine Datei schreibst, schreibst du nur den Pointer den der String intern benutzt in die Datei, nicht aber den Inhalt des dynamisch allokierten Speichers. Beim Lesen aus der Datei bastelst du dann die binäre Repräsentation eines Strings zusammen, der schon lang nichtmehr existiert und der vor allem schon seinen Speicher freigegeben hat. Damit gehört dieser Speicher längst jemand anderem, und trotzdem hat der string-Zombie aus der Datei noch einen Pointer auf den Speicher. Sobald er drauf zugreift krachts.
Was deinen aktuellen Code angeht: wieder etwas zu viel des Guten (die getter, setter, vergleiche usw. hätten wir nicht nochmal gebraucht), dafür fehlt das wichtigste, nämlich die main()-Funktion
-
die main ist ganz schön groß aber nagut:
#include "key verwalter.h" Key g_Keys[MAX_KEYS]; bool g_baHits[MAX_KEYS]; int main() { bool bError = false; string sInput; string sChildInput; if(load() == ERROR_READ) cout << "FEHLER: Die Datei data\\Keys.dat konnte nicht gelesen werden!\n\n"; string valid_inputs[]={"exit", "e", "add", "delete", "del", "search", "mod", "cls", "help", "h"}; enum valid_inputs_words{exit, e, addd, delee, del, searchh, modd, clss, helpp, h}; int valid_count = sizeof(valid_inputs)/sizeof(string); while(sInput != "exit" && sInput != "e") { anfang: do { cout << "Befehl> "; CIN.Read(); if(CIN.GetArgError(0) != ADVCIN_OK) { bError = true; cout << "FEHLER: Fehlerhafte Eingabe!\n\n"; } else { CIN.LowerArg(0); sInput = CIN.GetArgString(0); bError = false; } }while(bError == true); switch (find(valid_inputs, valid_inputs + valid_count, sInput) - valid_inputs) { case addd: { if(CIN.GetArgError(1) != ADVCIN_ERROR_NO_ARG && CIN.GetArgError(2) != ADVCIN_ERROR_NO_ARG) { if(add(CIN.GetArgString(1), CIN.GetArgString(2)) == ERROR_EXISTS) cout << "FEHLER: Der Key " << CIN.GetArgString(1) << " Existiert bereits!\n\n"; else cout << "Der Key wurde erfolgreich hinzugefuegt.\n\n"; if(save() == ERROR_WRITE) cout << "FEHLER: Es konnte nicht in die Datei data\\Keys.dat geschrieben werden!\n\n"; } else cout << "FEHLER: Falsche Parameter!\n\n"; break; } case delee: case del: { if(CIN.GetArgError(1) != ADVCIN_ERROR_NO_ARG) { cout << "WARNUNG: Sind sie sicher, dass sie den Key " << CIN.GetArgString(1) << " loeschen wollen? (J/N) > "; cin >> sChildInput; for(unsigned int i = 0; i < sChildInput.length(); ++i) sChildInput[i] = tolower(sChildInput[i]); if(sChildInput == "j" || sChildInput == "ja") if(dele(CIN.GetArgString(1)) == ERROR_NOT_FOUND) cout << "FEHLER: Der Key " << CIN.GetArgString(1) << " existiert nicht!\n\n"; else cout << "Der Key wurde erfolgreich geloescht.\n\n"; if(save() == ERROR_WRITE) cout << "FEHLER: Es konnte nicht in die Datei data\\Keys.dat geschrieben werden!\n\n"; } else cout << "FEHLER: Falscher Parameter!\n\n"; break; } case searchh: { if(CIN.GetArgError(1) != ADVCIN_ERROR_NO_ARG) { search(CIN.GetArgString(1)); if(!found(g_baHits)) { cout << "FEHLER: Der Key " << CIN.GetArgString(1) << " ist nicht vorhanden!\n\n"; } else { for(int i = 0; i < MAX_KEYS; i++) { if(g_baHits[i] == true) { cout << "Name: " << g_Keys[i].GetName() << "\n"; cout << "Key: " << g_Keys[i].GetKey() << "\n\n"; } } } } else cout << "FEHLER: Falscher Parameter!\n\n"; break; } case clss: { cls(); break; } case modd: { if(CIN.GetArgError(1) != ADVCIN_ERROR_NO_ARG && CIN.GetArgError(2) != ADVCIN_ERROR_NO_ARG && CIN.GetArgError(3) != ADVCIN_ERROR_NO_ARG) { if(mod(CIN.GetArgString(1), CIN.GetArgString(2), CIN.GetArgString(3)) == ERROR_NOT_FOUND) cout << "FEHLER: Der Key " << CIN.GetArgString(1) << " ist nicht vorhanden!\n\n"; else cout << "Der Key wurde erfolgreich geaendert.\n\n"; if(save() == ERROR_WRITE) cout << "FEHLER: Es konnte nicht in die Datei data\\Keys.dat geschrieben werden!\n\n"; } else cout << "FEHLER: Falsche Parameter!\n\n"; break; } case helpp: case h: { help(); break; } case exit: case e: { break; } default: { cout << "\nFEHLER: Unbekannter Befehl: " << sInput << "\n\n"; } } } if(save() == ERROR_WRITE) { cout << "FEHLER: Es konnte nicht in die Datei data\\Keys.dat geschrieben werden!\n"; cout << "Wollen sie trotzdem beenden? (J/N) > "; cin >> sInput; if(sInput != "j" || sInput == "ja") goto anfang; // sry für die eine Spaghetti ich war zu faul noch ne schleife einzubauen } return 0; }ich denke dann sollte ich euch auch mal über meine advcin klasse invormieren.
Ich denke die Definition reicht:
class advcin { public: advcin(); ~advcin(); void Read(bool bLower = false, int iNumArgs = 0); // Bei iNumArgs = 0 gibt es keine beschränkung außer die Länge der m_saArg std::string GetArgString(int) const; int GetArgError(int) const; void LowerArg(int iArg = -1); private: void Sort(int); void Clear(); std::string m_sAll; std::string m_saArg[MAX_ARGS]; };
-
Alter Verwalter! Lesbar ist etwas anderes. Lösche doch am besten die Teile, die mit dem Problem nix zu tun haben aus deinen Code(riesen)schnipseln. Gibt es das Wort "Schnips"? hehe
Das letzte Posting mag ich mir echt nicht durchlesen... Aber in dem davor sah es so aus, dass du in der Schleife immer die gleiche Datei öffnest, das erste Key-Value paar ausliest, die Datei schließt, wieder aufmachst, das erste Key-Value paar ausliest usw. usf. Das wolltest du so bestimmt nicht.
-
Decimad schrieb:
Alter Verwalter! Lesbar ist etwas anderes. Lösche doch am besten die Teile, die mit dem Problem nix zu tun haben aus deinen Code(riesen)schnipseln. Gibt es das Wort "Schnips"? hehe
Das letzte Posting mag ich mir echt nicht durchlesen... Aber in dem davor sah es so aus, dass du in der Schleife immer die gleiche Datei öffnest, das erste Key-Value paar ausliest, die Datei schließt, wieder aufmachst, das erste Key-Value paar ausliest usw. usf. Das wolltest du so bestimmt nicht............................................................. leider gibts hier keinen smilie der sich den kopf vor die wand haut!! also *BUUUMMM Kopf vordie Wand hau BBBBUUUUMMM*
danke!!!
ich bin echt ein idiot!!!!!!!!!!
-
so hab die sachen geändert und jetzt funktioniert es auch!!!
thx an alle die sich die mühe gemacht haben und sich durch meinen code gewühlt haben!!!!!!
/edit und hier nochmal die geänderten stellen:
int load() { ifstream fI("data\\Keys.dat", ios::binary); for(int i = 0; i < MAX_KEYS; i++) { if(!g_Keys[i].Load(fI)) return ERROR_READ; } fI.close(); fI.clear(); return OK; } int save() { ofstream fO("data\\Keys.dat", ios::binary | ios::trunc); for(int i = 0; i < MAX_KEYS; i++) { if(!g_Keys[i].Save(fO)) return ERROR_WRITE; } fO.close(); fO.clear(); return OK; } bool Key::Save(std::ostream const& o) { bool bGood; o.write((char *) &m_bExist, sizeof(bool)); writestring_binary(o, m_sName); writestring_binary(o, m_sKey); bGood = o.good(); return bGood; } bool Key::Load(std::istream const& i) { bool bGood; i.read((char *) &m_bExist, sizeof(bool)); readstring_binary(i, m_sName); readstring_binary(i, m_sKey); bGood = i.good(); return bGood; } void Key::writestring_binary( std::ostream const& o, std::string const& str ) { std::size_t temp = str.size(); o.write( (const char*) &temp, sizeof( std::size_t ) ); o.write( str.data(), str.size() ); } void Key::readstring_binary( std::istream const& i, std::string& str ) { std::size_t s; i.read( (char*)&s, sizeof( std::size_t ) ); str.clear(); str.reserve( s ); char c; for( std::size_t n = 0; n < s; ++n ) { i.get( c ); str += c; } }
-
Freut mich

Achso - zum Thema Foo und Bar:
http://en.wikipedia.org/wiki/Foo
-
thx