Mehrere Instanzen einer Klasse abspeichern


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



  • Wieso ist mir das noch nicht aufgefallen?

    Einerseits können chars und ints unterschiedlich gross sein

    Nein, die Größe von char, signed char und unsigned char ist vom Standard deutlich festgelegt: Genau ein Byte.



  • Sone schrieb:

    Wieso ist mir das noch nicht aufgefallen?

    Einerseits können chars und ints unterschiedlich gross sein

    Nein, die Größe von char, signed char und unsigned char ist vom Standard deutlich festgelegt: Genau ein Byte.

    Quizfrage:

    Programm A speichert 60 Bytes in eine Datei.
    Programm B liest die gesamte Datei, findet aber nur 40 Bytes vor.
    Kann das sein?



  • reinterpreter schrieb:

    Sone schrieb:

    Wieso ist mir das noch nicht aufgefallen?

    Einerseits können chars und ints unterschiedlich gross sein

    Nein, die Größe von char, signed char und unsigned char ist vom Standard deutlich festgelegt: Genau ein Byte.

    Quizfrage:

    Programm A speichert 60 Bytes in eine Datei.
    Programm B liest die gesamte Datei, findet aber nur 40 Bytes vor.
    Kann das sein?

    Nein. Wenn Programm A 60 chars in die Datei schreibt, dann findet Programm B auch 60 vor.



  • Sone schrieb:

    reinterpreter schrieb:

    Sone schrieb:

    Wieso ist mir das noch nicht aufgefallen?

    Einerseits können chars und ints unterschiedlich gross sein

    Nein, die Größe von char, signed char und unsigned char ist vom Standard deutlich festgelegt: Genau ein Byte.

    Quizfrage:

    Programm A speichert 60 Bytes in eine Datei.
    Programm B liest die gesamte Datei, findet aber nur 40 Bytes vor.
    Kann das sein?

    Nein. Wenn Programm A 60 chars in die Datei schreibt, dann findet Programm B auch 60 vor.

    Doch. Da nicht festgelegt ist, aus wie vielen Bits ein Byte besteht. Bei Programm A sind es 8 Bits, bei Programm B 12 Bits.

    C++11-Standard § 1.7/1 schrieb:

    The fundamental storage unit in the C++ memory model is the byte. A byte is at least large enough to contain
    any member of the basic execution character set (2.3) and the eight-bit code units of the Unicode UTF-8
    encoding form and is composed of a contiguous sequence of bits, the number of which is implementation-
    defined. The least significant bit is called the low-order bit; the most significant bit is called the high-order
    bit. The memory available to a C++ program consists of one or more sequences of contiguous bytes. Every
    byte has a unique address.

    Wobei anzumerken ist, dass es höchst ungewöhnlich ist, dass an dieser Stelle ein Fehler passiert, aber es ist durchaus denkbar.


Anmelden zum Antworten