Problem beim lesen und schreiben der Datei



  • Account::Account(const std::string& file) : filename(file)
    {
    
    	Lesefile();
    }
    
    Account::~Account()
    {
    	Aktuallisierefile();
    }
    
    void Account::Aktuallisierefile()
    {
    	std::ofstream writeAccs(filename);
            writeAccs.clear();
    	for (auto it : Users)
    	{
    		writeAccs << it.first << " " << it.second << std::endl;
    	}
    	writeAccs.close();
    }
    
    void Account::Lesefile()
    {
    	std::stringstream puffer;
    	std::string id, pw;
    	std::string zeile;
    	std::ifstream openfile(filename);
    	while (getline(openfile, zeile))
    	{
    		puffer.str(zeile);
    		puffer >> id >> pw;
    
    		Users.insert({ id, pw });
    	}
    	openfile.close();
    }
    

    Es wird keine neue Datei angelegt wenn nicht bereits 'filename' vorhanden ist
    was mache ich falsch?

    Das Programm soll Accounts in einer Datei speichern und die Account Daten bei jedem Programm start aus der Datei entnehmen ....
    Vor wenigen Tagen hat es noch ganz gut funktioniert doch heute funktioniert es pl├Âtzlich nicht mehr ­čśĽ ­čśĽ



  • Hat vermutlich nichts mit deinem Problem zu tun aber: Wieso close() in den Zeilen 20 und 36? Wieso liest du zuerst einen String ein und dann aus einem Stringstream? Lies direkt aus der Datei? Was passiert, wenn man den Account kopiert? Als eine Art Scopeguard solltest du so etwas verbieten.



  • Nathan schrieb:

    Hat vermutlich nichts mit deinem Problem zu tun aber: Wieso close() in den Zeilen 20 und 36? Wieso liest du zuerst einen String ein und dann aus einem Stringstream? Lies direkt aus der Datei? Was passiert, wenn man den Account kopiert? Als eine Art Scopeguard solltest du so etwas verbieten.

    Weil die Datei sonst offen bleibt und es zu fehlern f├╝hren kann schlie├če ich die Datei am ende der Funktionen

    Ich lese zuerst auf der Datei eine Zeile diese zerhacke ich dann in 2 w├Ârter und diese 2 w├Ârter repr├Ąsentieren die ID und das PW

    Die Kopierkonstruktoren bzw zuweisungsoperatoren habe ich schon verboten



  • Warum rufst du clear auf?
    M├Âglicherweise fehlt dem Programm das Recht, Dateien anzulegen.

    Wenn ein ofstream zerst├Ârt wird, wird die Datei geschlossen, ein explizites close ist in der Regel ├╝berfl├╝ssig!



  • CommuntityFan schrieb:

    Weil die Datei sonst offen bleibt und es zu fehlern f├╝hren kann schlie├če ich die Datei am ende der Funktionen

    Deine Account Klasse hat einen Destruktor, der automatisch die Accounts in die Datei schreibt. Glaubst du dann nicht, dass die Standardbibliothek auf die Idee kam einen Destruktor f├╝r ihre Filestreams zu schreiben, der selbige schlie├čt? (Rhetorische Frage)

    Ich lese zuerst auf der Datei eine Zeile diese zerhacke ich dann in 2 w├Ârter und diese 2 w├Ârter repr├Ąsentieren die ID und das PW

    Ja, das sehe ich. Wieso? Wieso liest du sie nicht direkt aus der Datei?



  • Nathan schrieb:

    Wieso close() in den Zeilen 20 und 36?

    manni66 schrieb:

    Wenn ein ofstream zerst├Ârt wird, wird die Datei geschlossen, ein explizites close ist in der Regel ├╝berfl├╝ssig!

    In der hier gezeigten Form bringt es nat├╝rlich tats├Ąchlich nichts.

    Grunds├Ątzlich ist es aber guter Stil Streams und ├Ąhnliche Objekte explizit zu schliessen. Und zwar weil das Schliessen implizit nen Flush macht, und der Flush kann schief gehen.
    Wenn man den Stream vom Dtor schliessen l├Ąsst gibt es nur zwei M├Âglichkeiten, die beide schlecht sind: Entweder der Dtor wirft eine Exception wenn beim Flushen ein Fehler auftritt, oder der Dtor ignoriert den Fehler einfach.

    Damit es mit std::ofstream wirklich was bringt m├╝sste man dann aber noch entweder
    a) Nach dem close() den Stream-State pr├╝fen oder
    b) Vor dem close() das Bit ios::failbit in der Exception-Maske des Streams setzen

    Dinge wie Streams, Files etc. sollte man nur per Dtor schliessen lassen wenn entweder bereits sichergestellt ist dass es nichts zu flushen gibt, oder wenn es vollkommen egal ist ob die Daten erfolgreich geflusht werden oder nicht. Und auch dann nur wenn man weiss wie die jeweilige Klasse darauf reagiert. std::ofstream ignoriert den Fehler z.B. einfach, statt eine Exception aus dem Dtor zu werfen - auch wenn ios::failbit in der Exception-Maske gesetzt ist. (Zumindest die Implementierung von VS2013 macht das so, ich hab' nicht im Standard nachgesehen was das vorgeschriebene Verhalten ist. Was mMn. auch sinnvoll ist, da Exceptions aus Destruktoren eher problematisch sind.)


Log in to reply