Mehrere Instanzen einer Klasse abspeichern



  • Vermutlich spricht gegen XMl, dass XML kacke ist.

    Warum ?



  • sulky schrieb:

    aber das noch viel grössere Problem ist folgendes:
    Wenn ich die Klasse element erweitere um:

    element*next;
    

    so kann ich in der einschreibefunktion noch schreiben:

    os<<e.a<<e.s<<e.next;
    

    aber in der ausgabefunktion folgt eine Fehlermeldung auf

    is>>e.a>>e.s;>>e.next;
    

    wieso das?

    Du kannst nicht erwarten, dass Du den Zeiger einfach wegschreiben kannst, danach wieder einliest und der immer noch auf was sinnvolles zeigt.
    Schreib den Zeiger nicht, lies den Zeiger nicht, sondern bau Deine Datenstruktur beim lesen wieder neu auf.



  • Ich erlaube mir das hier als Lektüre:

    http://www.c-plusplus.net/forum/239586

    Und zwar der Link auf "Kapitel 24: Wie man Zeiger in Dateien speichert".

    Das spricht das Thema teilweise an.



  • Bitte ein Bit schrieb:

    Vermutlich spricht gegen XMl, dass XML kacke ist.

    Warum ?

    - Unleserlich
    - Kompliziert/aufwaendig
    - Kompletter Overkill bei 99% der Anwendungen, die ich bisher gesehen habe.

    ... davon abgesehen sind Binaerformate grundsaetzlich besser.


  • Mod

    Kellerautomat schrieb:

    ... davon abgesehen sind Binaerformate grundsaetzlich besser.

    😕

    - Unleserlich
    - Kompliziert/aufwaendig
    - Kompletter Overkill bei 99% der Anwendungen, die ich bisher gesehen habe.



  • SeppJ schrieb:

    - Unleserlich

    Noe, gar nicht lesbar. Das war aber auch gar nicht die Anforderung. Lieber ein gar nicht lesbares Binaerformat, als ein unleserliches Textformat.

    SeppJ schrieb:

    - Kompliziert/aufwaendig

    Noe. Das Parsen/Generieren von lesbarem Text entfaellt voellig. Man muss sich nicht mit laestigen Zeichenkodierungen herumschlagen. Oder Escape-Sequenzen.

    SeppJ schrieb:

    - Kompletter Overkill bei 99% der Anwendungen, die ich bisher gesehen habe.

    Dann lass die Dateien am besten gleich bleiben.


  • Mod

    Kellerautomat schrieb:

    SeppJ schrieb:

    - Unleserlich

    Noe, gar nicht lesbar. Das war aber auch gar nicht die Anforderung.

    Aber es war dein Kritikpunkt an XML. Bei Binärformat ist dieser Nachteil nochmals unendlich viel schlimmer ausgeprägt

    SeppJ schrieb:

    - Kompliziert/aufwaendig

    Noe. Das Parsen/Generieren von lesbarem Text entfaellt voellig. Man muss sich nicht mit laestigen Zeichenkodierungen herumschlagen.

    Dann zeig mal wie du einen std::string binär abspeicherst.

    SeppJ schrieb:

    - Kompletter Overkill bei 99% der Anwendungen, die ich bisher gesehen habe.

    Dann lass die Dateien am besten gleich bleiben.

    Wo ist der Vorteil des Binärformates? Größe der Datei, eventuell leicht höhere Parse-Geschwindigkeit. Bei welcher Anwendung ist dies wichtig? Falls Größe kritisch ist, zippt man die Datei eben noch. Wenn Geschwindigkeit beim Parsen wichtig ist, dann macht man wahrscheinlich etwas falsch.

    Dafür hat das Binärformat aber ähnlich Komplikationen (Kritikpunkt 2) und den dicken Nachteil, gar nicht lesbar/editierbar zu sein. Man sollte seinen Einsatz daher schon sehr gut Begründen und es sollte nicht der Normalfall sein.



  • SeppJ schrieb:

    Aber es war dein Kritikpunkt an XML. Bei Binärformat ist dieser Nachteil nochmals unendlich viel schlimmer ausgeprägt

    Also ich finde ein struct in meiner Anwendung, in das diese Daten Member fuer Member hineingelesen werden, wesentlich lesbarer.

    SeppJ schrieb:

    Dann zeig mal wie du einen std::string binär abspeicherst.

    Ein std::string weiss nichts von Zeichenkodierungen.

    SeppJ schrieb:

    Wo ist der Vorteil des Binärformates? Größe der Datei, eventuell leicht höhere Parse-Geschwindigkeit. Bei welcher Anwendung ist dies wichtig? Falls Größe kritisch ist, zippt man die Datei eben noch. Wenn Geschwindigkeit beim Parsen wichtig ist, dann macht man wahrscheinlich etwas falsch.

    Ein Binaerformat ist viel leichter zu implementieren und benoetigt keine Fremdlibs.


  • Mod

    Kellerautomat schrieb:

    SeppJ schrieb:

    Aber es war dein Kritikpunkt an XML. Bei Binärformat ist dieser Nachteil nochmals unendlich viel schlimmer ausgeprägt

    Also ich finde ein struct in meiner Anwendung, in das diese Daten Member fuer Member hineingelesen werden, wesentlich lesbarer.

    Lesbarer als welche Alternative? Alle vernünftigen Formate machen das so. Außerdem meine ich die Lesbarkeit des Formates. Meintest du etwa bisher den Code?

    SeppJ schrieb:

    Dann zeig mal wie du einen std::string binär abspeicherst.

    Ein std::string weiss nichts von Zeichenkodierungen.

    Zeig mal wie du ihn binär speicherst. Los.

    Im übrigen sind Binärformate codegewordene Portabilitätsprobleme. Ziechencodierungen sind ein lächerlich geringes Problem gegen die Probleme, die du beim portieren von naiv geschriebenen Binärdaten bekommst. Und wenn du sie nicht naiv schreibst, hast du wieder eine komplexe Formatierungsaufgabe. Wieso dann die Nachteile des Binärformates in Kauf nehmen, wenn man auch gleich ein lesbares Format haben könnte.

    SeppJ schrieb:

    Wo ist der Vorteil des Binärformates? Größe der Datei, eventuell leicht höhere Parse-Geschwindigkeit. Bei welcher Anwendung ist dies wichtig? Falls Größe kritisch ist, zippt man die Datei eben noch. Wenn Geschwindigkeit beim Parsen wichtig ist, dann macht man wahrscheinlich etwas falsch.

    Ein Binaerformat ist viel leichter zu implementieren und benoetigt keine Fremdlibs.

    Welche Fremdlibs brauchst du für ein lesbares Format? Zeig mal eine Implementierung für dein Binärformat, welche nicht die von dir dem lesbaren Format zugeschriebenen Mängel hat.

    P.S.: Irgendwie entsteht bei mir der Eindruck, dass du mir absichtlich das Wort im Mund verdrehst, weil du kein Unrecht eingestehen willst. Falls ich dir da Unrecht tue: Du solltest besser aufpassen, was du wie formulierst. Falls ich dies richtig erkannt habe: 🙄



  • @Kellerautomat
    XML ist weder kompliziert noch unleserlich, und Binärformate sind in den meisten Fällen keine sinnvolle Alternative.
    Binärformate sind schlecht erweiterbar, daher schlecht wartbar und grundsätzlich total unleserlich.

    Das einzige was mMn. gegen XML spricht ist dass XML in C++ etwas fummelig zu verwenden ist.



  • Mich nervt bei XML besonders der Overhead. Das bläht eine ansonsten recht kleine Datei doch sehr auf.


  • Mod

    Braunstein schrieb:

    Mich nervt bei XML besonders der Overhead. Das bläht eine ansonsten recht kleine Datei doch sehr auf.

    Man muss ja auch nicht zwangsläufig gleich zu XML greifen. Bei sehr vielen Anwendungen reichen Formate wie "Alle Zahlen nacheinander", "Ein String pro Zeile" oder auch das gute alte CSV. Hier im Thread ist das Problem, dass uns fast überhaupt gar nichts über die Daten und die Anwendung bekannt ist, das läuft dann bei den Antworten eben auf allerallgemeinste Formate hinaus.



  • sulky schrieb:

    aber in der ausgabefunktion folgt eine Fehlermeldung auf

    is>>e.a>>e.s;>>e.next;
    

    wieso das?

    Wie soll dir jemand die Frage beantworten, wenn du noch nicht einmal die Fehlermeldung nennst und wann du sie bekommst?
    Im Zweifelsfall hast du die Zeile tatsächlich so geschrieben und ein ; zuviel.



  • Sorry aber deine Lösung ist für mich ein Hack.

    Blödsinn, das ist die Standardlösung für Array-Serialisierungen.

    Wer garantiert dass das Format sauber dokumentiert wird, s.d. in 5 Jahren, wenn jemand den Code wieder anfasst, das Datenformat auch ohne Probleme versteht.

    Wovon redest du?

    Was spricht dagegen in solchen Fällen die Klassendefinitionen ins XML Format zu wandeln. Ist lesbarer als deine Lösung und eindeutiger definiert.

    Lol, das ist jetzt nicht dein ernst, oder? 👎 😮



  • Hallo zusammen, vielen Dank für eure Hilfe.
    Auch wenn ich nicht alles bis ins detail verstehen konnte.

    Hier nochmals meine Klasse. Neu will ich (auf Rat aus diesem Forum) den Zeiger auf die nächste Instanz nicht mehr mit abspeichern, da nach einem Computerneustart die Instanz wohl kaum mehr an der gleichen Stelle befinden
    wird.

    class element
    {
    public:
    int a;
    string s;
    element*next;
    
    friend ostream& operator<<(std::ostream& os, element const& e)
        {
            os<<e.a<<e.s;
    
    		// Die ganzen Member von e in os reinschreiben
             return os; // Referenz auf Stream zurückgeben -> damit os << a << b << c möglich wird
        }
    
    friend istream& operator>>(std::istream& is, element& e)
        {
             is>>e.a>>e.s;
             return is; // ~ zurückgeben -> damit is >> a >> b >> c möglich wird.
        }
    };
    

    und hier das Testprogram, welches auch funktioniert:

    int _tmain(int argc, _TCHAR* argv[])
    {
    element m;
    m.a=7;
    m.s="hallo";
    
    std::ofstream os("Bla.txt");
    os << m; 
    os.close();
    
    std::ifstream stream("Bla.txt");
    element k;
    stream >> k;
    
    cout<<k.a<<"   "<<k.s<<endl;
    }
    

    Nun möchte ich ja aber nicht eine Instanz abspeichern, sondern mehrere:
    Dazu erweitere ich mein Testprogram wie folgt:

    int _tmain(int argc, _TCHAR* argv[])
    {
    element m;
    m.a=7;
    m.s="hallo";
    
    element n;
    n.a=5;
    n.s.hello;
    
    std::ofstream os("Bla.txt");
    os << m; 
    
    //hier stehe ich an. Jetzt möchte ich n doch auch noch in die selbe    
    //datei speichern
    
    os.close();
    
    std::ifstream stream("Bla.txt");
    element k;
    element l; //nun brauche ich ein zweites Element, welches n ersetzt 
    stream >> k;
    
    stream >> l; //ob dies so richtig ist, bin ich mir überhaut nicht sicher.
    
    cout<<k.a<<"   "<<k.s<<endl;
    
    cout<<l.a<<"   "<<l.s<<endl; //und auch hier der Test, ob l und n identisch sind
    }
    

    nun sind folgende Probleme noch ungelöst:

    1. Wie schreibe ich ein zweites Element in dieselbe datei?
    2. Funkioniert das lesen des zeiten Elementes auf diese Weise?
    3. (Bereits in diesem Forumsbeitrag erwähnt) Wie passe ich den String an, damit
    nicht aus "Hallo Welt" ein "Hallo" wird.



  • 1. Genau wie beim ersten Element auch:

    Datei << Element1; 
    Datei << Element2;
    

    2. Das funktioniert also genau andersrum:

    Element Element1;
    Element Element2;
    
    Datei >> Element1; 
    Datei >> Element2;
    

    3. Speicher den std::string z.B. als eigene Zeile und lies ihn mit std::getline wieder aus.



  • hallo jjjjj
    VIelen Dank für deine Antwort.
    Leider funktioniert es noch nicht.

    Hier nochmals das angepasste Program:
    Die Klasse ist unverändert.

    int _tmain(int argc, _TCHAR* argv[])
    {
    element m,n;
    m.a=7;
    m.s="hallo";
    
    n.a=5;
    n.s="hello";
    
    std::ofstream os("Bla.txt");
    os << m;
    os<< n;
    os.close();
    
    std::ifstream stream("Bla.txt");
    element k,l;
    stream >> k;
    stream >>l;
    
    cout<<k.a<<"   "<<k.s<<endl;
    cout<<l.a<<"   "<<l.s<<endl;
    }
    

    Konsolenausgabe:
    7 hallo5hello
    -895993460

    Erst dachte ich, es läge daran, dass ich den String noch nicht so eingelesen habe, wie du es empfohlen hast und das Program deshalb nicht erkennt wo der string zu ende ist. Dann habe ich aber sämtliche Strings entfernt und einen Test gemacht. Hat aber nicht funktioniert.
    Was läuft da noch schief?



  • Probier mal:

    os << m << std::endl;
    os << n << std::endl;
    

    Ansonsten zeig nochmal den aktuellen Code (insbesondere die Operatoren >> und << in der Klasse)



  • Fantastisch! Jetzt klappts.

    Aber ich schreibe den String immer noch nicht als zeile in die datei. Kann dies späternoch zu problemen führen?



  • sulky schrieb:

    Fantastisch! Jetzt klappts.

    Aber ich schreibe den String immer noch nicht als zeile in die datei. Kann dies späternoch zu problemen führen?

    Durch das std::endl tust du das indirekt. Denn std::endl schreibt auch eine Leerzeile in die Datei.

    Ich habe dir in deinem anderen Thread dazu noch ausführlicher geantwortet. Am besten experimentierst du damit ein wenig rum und schaust dir auch mal die Datei Bla.txt an. Das sollte Klarheit schaffen.


Anmelden zum Antworten