Struct in Datei schreiben aus CodeGuru.com


  • Mod

    Kellerautomat schrieb:

    Edit 2: Und dass manche Leute hier jedes Mal aufs neue Messungen verlangen, wenns um istream(buf)_iterator vs read geht, ist einfach nur noch laecherlich. Wir hatten diese Vergleiche schon zig mal, und in so ziemlich jedem Fall ist rausgekommen, dass Iteratoren signifikant langsamer sind. Findet euch damit ab.

    Klar sind die langsamer als read. Aber langsamer als die Implementierung mit dem temporären Zwischenvector? Wohl kaum.



  • SeppJ schrieb:

    Klar sind die langsamer als read. Aber langsamer als die Implementierung mit dem temporären Zwischenvector? Wohl kaum.

    Kann ich mir sehr gut vorstellen, dass das langsamer ist. Zumal man eben keinen Zwischenvektor braucht.


  • Mod

    Kellerautomat schrieb:

    SeppJ schrieb:

    Klar sind die langsamer als read. Aber langsamer als die Implementierung mit dem temporären Zwischenvector? Wohl kaum.

    Kann ich mir sehr gut vorstellen, dass das langsamer ist. Zumal man eben keinen Zwischenvektor braucht.

    Lies den Thread. Es ging um eine ganz streng C++98-konforme Implementierung (Speicherlayout von string kann nicht-kontinuierlich sein), da kommt man tatsächlich nicht ohne Zwischenvector aus, wenn man keine Iteratoren will.
    (Wobei, wenn ich mich recht entsinne, in C++98 theoretisch ein standardkonformer vector möglich wäre, der intern rückwärts im Speicher liegt. In dem Fall wären die Iteratoren sogar die einzige pedantisch portable Methode)



  • keine ahnung schrieb:

    char* pointerToData = "test"/* ... */; 
    int dataLen = 4/* ... */; 
    std::string data; 
    data.append(pointerToData, dataLen);
    

    Die frage bleibt, wo kommt der Zeiger auf char her, wenn ich nur die Länge aus der Datei mit >>len ,gelesen habe.

    Das war nur ein unpassendes Beispiel wie du N chars aus einem pointer in einen string kopierst.. Vergiss das bitte wieder, hat für dich keine Relevanz. 🙂
    Das war nur für den Fall dass du keine streams hast, sorry wollte dich nicht verwirren. 😞

    Nimm einfach:

    void writeString(std::fstream &file, std::string &str)
    {
    	file << str.length() << ' '; //write length and seperator
    	file << str; //write string
    }
    
    std::string readString(std::fstream &file)
    {
    	int len;
    	file >> len; // Read length
    	file.ignore(); //skip ' '
    	std::string data;
    	data.resize(len); //reserve space for string
    	file.read(&data[0], len); //read string
    	return data;
    

    So sollte es jetzt aber endlich passen. Die Zahl wird als Text in die Datei geschrieben, dann ein Trennzeichen um die Zahl vom string abzugrenzen, und dann der string.
    Wenn jemand ne Lösung hast wie man das Trennzeichen besser überspringt nur her damit.



  • int fuer Laengen ist ne Schnapsidee.



  • Kellerautomat schrieb:

    int fuer Laengen ist ne Schnapsidee.

    In 99% der Fälle ist ein int größer als 16Bit, d.h. mindestens 32Bit und damit völlig ausreichend. In welchem Fall könnte das denn zum Problem werden ?
    Aber gut, machen wir ein "uint32_t" draus. 😃


  • Mod

    Weil ein String groesser als 2(4) GiB gross werden kann.
    Weil der Extraktionsoperator ein Minuszeichen vor der Laenge als korrekt sieht und eine negative Laenge setzt.

    Nimm std::size_t oder std::string::size_type , die duerften auf 64-Bit Systemen auch 8 Byte gross sein.



  • Arcoth schrieb:

    Weil ein String groesser als 2(4) GiB gross werden kann.

    Aber kein normaler string sollte so lang werden. Und wenn doch hast du ein Designproblem.
    Andere Sprachen limitieren die Länge von strings auch auf 32Bit Integer, und ich habe noch nie gehört dass das ein Problem darstellt. 😉

    Arcoth schrieb:

    Weil der Extraktionsoperator ein Minuszeichen vor der Laenge als korrekt sieht und eine negative Laenge setzt.

    Kommt aber im normalen Gebrauch nie vor. Und wenn ich das Program crashen will, kann ich auch die Länge zu groß/klein machen, oder gleich weglassen...



  • @DarkShadwo44 & Kellerautomat :

    Vielen Dank, ist jetzt soweit klar, danke nochmals für euere ausführliche Hilfe.


  • Mod

    @Darkshadow44: Deine Argumentation ist komisch. Erst einmal die Fakten:
    -Mit size_t ist das Programm immer richtig.
    -Mit einem anderen Typen manchmal nicht.
    Wie kannst du da ernsthaft für die anderen Typen argumentieren? Wenn doch der einzige Unterschied im Code ist, was du an der Stelle des Typs schreibst. uint32_t ist ja nicht einmal einfacher zu tippen als size_t !



  • size_t ist aber plattformabhaengig. Das Richtige ist also, sich auf einen fixen Typen festzulegen und beim Speichern checken, ob die Laenge des Strings in den Typen passt.


  • Mod

    Kellerautomat schrieb:

    size_t ist aber plattformabhaengig. Das Richtige ist also, sich auf einen fixen Typen festzulegen und beim Speichern checken, ob die Laenge des Strings in den Typen passt.

    Und inwiefern hilft dabei eine künstliche Beschränkung auf uint32_t? Das Problem bleibt das gleiche, aber dafür funktioniert das Programm suboptimal auf (den vielen) Plattformen, die mehr könnten.



  • Entscheide dich eben, was du willst: Binaer kompatible Files oder Plattformen voll ausnutzen. Beides kriegt du eben nur mit VarInts, aber auch dann kannst du nicht erwarten, dass sich >4GB Strings auf 32-Bit Plattformen lesen lassen.

    Deshalb habe ich dem TE auch nicht gesagt "X ist der kanonische Weg" sondern "das sind die Trade-Offs".


  • Mod

    Kellerautomat schrieb:

    Entscheide dich eben, was du willst: Binaer kompatible Files oder Plattformen voll ausnutzen.

    Ich wähle: Beides auf einmal! Ich verstehe echt nicht, wo du hier das Problem siehst. Du scheinst irgendwie nur die Hälfte der Beiträge gelesen zu haben und dabei sind dir ein paar wichtige Posts entgangen, die das Missverständnis klären könnten.



  • SeppJ schrieb:

    Kellerautomat schrieb:

    Entscheide dich eben, was du willst: Binaer kompatible Files oder Plattformen voll ausnutzen.

    Ich wähle: Beides auf einmal! Ich verstehe echt nicht, wo du hier das Problem siehst.

    Dann erklaer mal, wie das funktioniert. size_t faellt schon mal raus, weil er keine fixe Laenge hat. Was nimmst du?


  • Mod

    Kellerautomat schrieb:

    SeppJ schrieb:

    Kellerautomat schrieb:

    Entscheide dich eben, was du willst: Binaer kompatible Files oder Plattformen voll ausnutzen.

    Ich wähle: Beides auf einmal! Ich verstehe echt nicht, wo du hier das Problem siehst.

    Dann erklaer mal, wie das funktioniert. size_t faellt schon mal raus, weil er keine fixe Laenge hat. Was nimmst du?

    size_t! Du machst dir Probleme, die gar nicht da sind. Du sollst nicht die Länge binär speichern!



  • SeppJ schrieb:

    size_t! Du machst dir Probleme, die gar nicht da sind. Du sollst nicht die Länge binär speichern!

    Binaer und formatiert mischen finde ich ganz doof.


  • Mod

    Kellerautomat schrieb:

    SeppJ schrieb:

    size_t! Du machst dir Probleme, die gar nicht da sind. Du sollst nicht die Länge binär speichern!

    Binaer und formatiert mischen finde ich ganz doof.

    Also ein emotionales Argument? Die perfekte(!) Lösung wird nicht genommen, weil der Herr sich nicht wohl fühlt?


  • Mod

    Kellerautomat schrieb:

    Binaer und formatiert mischen finde ich ganz doof.

    Ich nicht.



  • SeppJ schrieb:

    Kellerautomat schrieb:

    SeppJ schrieb:

    size_t! Du machst dir Probleme, die gar nicht da sind. Du sollst nicht die Länge binär speichern!

    Binaer und formatiert mischen finde ich ganz doof.

    Also ein emotionales Argument? Die perfekte(!) Lösung wird nicht genommen, weil der Herr sich nicht wohl fühlt?

    Sowas nennt man dann inkonsistent. VarInts koennen genau dasselbe, nur besser.


Anmelden zum Antworten