Vektor serialisieren oder in Array kopieren?



  • Hallo

    Ich möchte einen Vektor in einen Data-Stream umwandeln um ihn anschliessend Binär zu speichern.

    Der Vektor ist vom Typ Klasse.

    Habe gelesen das es relativ umständlich ist einen vector zu serialisieren. Folgendes habe ich programmiert:

    Marke *a = new Marke [vec.capacity()];
    copy(vec.begin(), vec.end(), a);
    

    Dieser Code kopiert den kompletten Vektor in einen dynamischen Array welchen man nachher Binär abspeichern könnte. Um die Datei wieder zu lesen müsste man den Inhalt wieder in einen Array kopieren und mit push_back in einen Vektor kopieren. Etwas aufwendig, macht das Sinn?

    Ich suche eine saubere und übersichtliche Lösung für ein eigenes Projekt. Was meint ihr?
    Danke für etwas Hilfe 🙂



  • einen Vector einer unbekannten Klasse einfach so zu serialisieren kann problematisch werden. Wenn du Compiler wechselst (oder gar nur die Compilerflags!) kann es sein, dass deine Klasse eine andere binaere Darstellung erhaelt und du mit der "alten Version" erzeugte Dateien nicht mehr einlesen kannst. Wenn du es also ganz sauber machen willst, schau mal bei boost vorbei, da gibts eine "saubere" Klassenserialisierung.

    Ansonsten waers nicht schlecht, wenn du einfach den operator<< von Klasse ueberladen wuerdest und dann einfach durch den vektor durchiterierst und ihn ueber den Stream ausgibst:

    std::copy(v.begin(), v.end(), std::output_iterator<Klasse>(my_file_output));
    

    via eines entsprechend ueberladenen operator>> kannst du die Daten dann ganz einfach wieder einlesen (am einfachsten tust du dich, wenn die Datei auch Informationen darueber enthaelt, wieviele Klasse-Objekte es gibt).

    Und am haesslichsten ists schliesslich, wenn du einfach ueber ostream::write() die Daten binaer rausschreibst, aber das waer einfach nur noch haesslich 😉

    Mein Rat: ueberlad operator>> und operator<<, das ist vermutlich am leichtesten 🙂



  • Hallo

    vector<char> vec;
        vec.push_back('A');
    	vec.push_back('B');
    
    	ofstream ofs("xxx.bin", ios::binary);
    	vector<char>::iterator output_iterator = vec.begin ();
    	copy(vec.begin(), vec.end(), output_iterator<char>(ofs));
    

    Wollte zum testen ein char-vector speichern. Bekomme aber den Fehler : error C2062: 'char'-Typ unerwartet.

    Komisch... sieht jemand den Fehler? Ahja wie sieht dann eigentlich der Befehl zum schreiben ofs.write aus?

    Danke



  • Typhoon schrieb:

    ...Ich möchte einen Vektor ... Binär ... speichern....

    Lieber nicht.
    Natürlich geht es prinzipiell, hat aber kaum Vor- und viele Nachteile.

    Wenn Du das hier ...

    Typhoon schrieb:

    Ich suche eine saubere und übersichtliche Lösung für ein eigenes Projekt. Was meint ihr? ...

    ... wirklich ernst meinst (und es ist ein wirklich guter Ansatz), dann speichere Deine Daten "lesbar" mittels operator<<().
    z.B. so ähnlich wie in :

    ostream& operator<<(ostream& ost, myVector const& v) {
       ost << v.size() << ' ';
       for(myVector::const_iterator it=v.begin(); it != v.end(); ++it) ost << *it << ' ';
       return ost << '\n';
    }
    

    Du kannst mit Trennern&Co. natürlich rumspielen, wie es Dir behagt und auch die vorangestellte Länge ist auch nur eine Möglichkeit, aber das direkte Verwenden von operator<<() (und zum Einlesen operator>>()) macht Vieles intuitiver und generischer.
    ... und vor Allem der Verzicht auf eine "Binärspeicherung" umschifft zahllose Klippen, wofür Du im Laufe des Projekts noch danlbar sein wirst.

    Gruß,

    Simon2.



  • Hab ich etwas verpeilt, da wirst du wohl recht haben.
    Ich arbeite mich morgen mehr in das Thema.

    Danke



  • Guten Morgen

    Ich habe den << Operator mal überladen

    std::ostream& operator<<(std::ostream& ost, CMyClass const& v) { 
       ost << v.get_name() << ' ' << v.get_infos(); 
       return ost << '\n'; 
    };
    

    In der main mach ich dann

    for (vector<CMyClass>::const_iterator i = vec.begin(); i != vec.end(); ++i)
        schreiben << *i;
    

    um das ganze zu schreiben.

    Funktioniert prima, was ich nicht hinkriege ist die for Schleife direkt in die Überladung einzubauen

    for(vector<CMyClass>::const_iterator it=v.begin(); it != v.end(); ++it) ost << *it << ' ';
    

    Bekomme immer Fehler, kann ich da überhaupt auf den vector zugreifen? 😕

    Wenn man die Daten getrennt mit Leerzeichen in Textdateien schreibt kann es doch zu üblen Fehlern kommen wenn Inhalte vom vector auch Leerzeichen haben? Wie umgeht man das Problemt?

    Gruss



  • Was bekommst du den für Fehler?



  • std::ostream& operator<<(std::ostream& ost, vector<CMyClass> const& v) { 
       ost << v.size() << ' '; 
       for(vector<CMyClass>::const_iterator it=v.begin(); it != v.end(); ++it) ost << *it << ' '; 
       return ost << '\n'; 
    }
    

    Hatte einen kleinen Verständnisfehler, aber funktioniert noch nicht

    error C2679: Binärer Operator '<<': Es konnte kein Operator gefunden werden, der einen rechtsseitigen Operanden vom Typ 'const CMyClass' akzeptiert (oder keine geeignete Konvertierung möglich)

    Gruss



  • Ist den ein << - Operator für CMyClass definiert?



  • Nein...

    Jetzt gehts omg 😃


Anmelden zum Antworten