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.)


Anmelden zum Antworten