Struct in Datei schreiben aus CodeGuru.com
-
Kellerautomat schrieb:
Ich stimme mal DarkShadow44 zu. Ihr habt doch alle einen Finderabdruck an der essbaren Waffel.
Irgendwann wirst Du dabei noch erwischt, wie Du Flüßigkeit in den Briefkasten schüttest und dann klicken die Hanschellen....
-
Kellerautomat schrieb:
Ich stimme mal DarkShadow44 zu. Ihr habt doch alle einen an der Waffel.
Wenn weiter so sachlich argumentiert wird, kann ich den Thread auch schließen. Möchtest du nicht noch sagen, dass wir hässlich sind und daher keiner Ahnung haben? Oder uns mit Hitler vergleichen?
-
SeppJ schrieb:
Wenn weiter so sachlich argumentiert wird, kann ich den Thread auch schließen.
Was soll ich dazu sagen? Du kommst doch hier mit so nem formatiert/binaer-Mischmasch der die Nachteile von beidem vereint.
Und dann ist dann noch Hacker, der es skandaloes findet, dass es Leute gibt, die mit Strings <4GB auskommen. Unfassbar, verbrennt sie!Splitte den Thread am besten oder so.
SeppJ schrieb:
Möchtest du nicht noch sagen, dass wir hässlich sind und daher keiner Ahnung haben? Oder uns mit Hitler vergleichen?
Keine Ahnung was das jetzt sein soll. Aber wo du schon danach fragst: Hacker spreche ich in der Tat einige Kompetenzen ab. Er hat in der Vergangenheit schon oft genug bewiesen, dass er keinen Plan hat und sein Verhalten hier bestaetigt das nur ein weiteres Mal.
Was bei dir los ist, weiss ich nicht :p
-
Kellerautomat schrieb:
Er hat in der Vergangenheit schon oft genug bewiesen, dass er keinen Plan hat und sein Verhalten hier bestaetigt das nur ein weiteres Mal.
Man könnte meinen du spricht über dich selbst.
-
hustbaer schrieb:
Man könnte meinen du spricht über dich selbst.
Keine Ahnung wovon du sprichst, ich hab eigentlich bisher mit relativ wenigen Leuten Probleme gehabt.
-
Er hat in der Vergangenheit schon oft genug bewiesen, dass er keinen Plan hat und sein Verhalten hier bestaetigt das nur ein weiteres Mal.
lol.
Was bei dir los ist, weiss ich nicht
Sobald jemand den du für kompetenter als dich selbst hältst deine Meinung nicht teilt verstehst du die Welt nicht mehr?
Ist nichts neues.
Und dann ist dann noch Hacker, der es skandaloes findet, dass es Leute gibt, die mit Strings <4GB auskommen.
Nein, ich halte es nur für angebracht dass der einzige Fall indem Unterschiede der beiden Methoden vorliegen berücksichtigt wird. Und es einfach zu leugnen ist völlig bescheuert.
-
Kellerautomat schrieb:
SeppJ schrieb:
Wenn weiter so sachlich argumentiert wird, kann ich den Thread auch schließen.
Was soll ich dazu sagen? Du kommst doch hier mit so nem formatiert/binaer-Mischmasch der die Nachteile von beidem vereint.
WTF?
DarkShadow44 schrieb:
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;
Länge menschenlesbar, String binär. Dummerweise Länge als int.
Deine direkte Antwort darauf:
Kellerautomat schrieb:
int fuer Laengen ist ne Schnapsidee.
Geschichtsverdrehung?
der die Nachteile von beidem vereint.
Erklär mal. Danach frage ich schon seit 5 Seiten. Bisher kam von dir nur "inkonsistent", "mag ich nicht", "braucht keiner", "Hacker ist doof", "du hast einen an der Waffel", usw. Sachgehalt: 0. Aggressives Verhalten: Hoch.
Um mal einen anderen Thread zu zitieren: Du bist gerade dabei, deinen Account zu verbrennen.
-
SeppJ schrieb:
DarkShadow44 schrieb:
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;
Länge menschenlesbar, String binär. Dummerweise Länge als int.
Deine direkte Antwort darauf:
Kellerautomat schrieb:
int fuer Laengen ist ne Schnapsidee.
Geschichtsverdrehung?
Hm, ich habe das jetzt nochmal genauestens nachgelesen. Scheinbar hatte ich das wirklich falsch in Erinnerung. Wenn das so ist, entschuldige ich mich bei dir hiermit.
SeppJ schrieb:
der die Nachteile von beidem vereint.
Erklär mal. Danach frage ich schon seit 5 Seiten. Bisher kam von dir nur "inkonsistent", "mag ich nicht", "braucht keiner", "Hacker ist doof", "du hast einen an der Waffel", usw. Sachgehalt: 0. Aggressives Verhalten: Hoch.
Der Sinn von formatierter IO ist, dass Menschen es lesen koennen. Eine Moeglichkeit waere daher, den String in Quotes zu stecken, alle nicht druckbaren Zeichen zu escapen und das dann rauszuschreiben. Bei Lesbarkeit failed die Variante also schon mal, weil es da ein Laengen-Prefix gibt, u.U. "irgendwelche komischen Zeichen", usw..
Bleibt noch binaere IO. Vorteile: Schnell, easy zu parsen. Tja, und da failed die Variante wieder. Ein paar Bytes in einen integer direkt einlesen ist wesentlich einfacher und schneller als einen Zahlenstring einzulesen, in einen integer umzuwandeln, dabei auf Ueberlaeufe zu checken usw.
Ich sehe darin also keine Vorteile, nur Nachteile.
-
Zwei Fehler:
-Vorteile formatierter IO ist nicht nur Menschenlesbarkeit. Ein Hauptvorteil ist Portabilität.
-Ich habe keine Ahnung, wieso du hier Zeichen escapen willst beim String. Es geht schon um binäre Speicherung des Strings. Es geht darum wie du die Länge mitbekommst. Da gibt es eben zwei Methoden, eine unportabel (und meinetwegen 3 µs schneller) und eine portabel.
-
SeppJ schrieb:
Zwei Fehler:
-Vorteile formatierter IO ist nicht nur Menschenlesbarkeit. Ein Hauptvorteil ist Portabilität.Warum sollte binäres Schreiben von Integern nicht portabel lösbar sein? Wenn du das als Nachteil anführst musst du als Gegenargument aber auch die bessere Performance akzeptieren.
Arcoth schrieb:
Als ob das vergleichbar wäre.
Und ob.
Nein.
Arcoth schrieb:
Ich brauche einen
std::string
größer als 4 GiB (bitte Binärpräfixe nutzen), deine These ist widerlegt.Höchstens meine These dass du dann ein Designproblem hast. :p
SeppJ schrieb:
Bei Arrays sehe ichs ja noch ein, aber definitiv nicht für std::string.
Und womit speicher ich mein OTP? vector<char>, obwohl's doch eine Zeichenkette ist? Wie speicherst du vector<char> ab? Auf einmal doch mit size_t?
Du braucht ein OPT dass größer als 4GB ist auf einmal im Speicher? Sicher dass du dein Design nicht nochmal überdenken willst?
Im übrigen sind OTPs idR nicht nur Text, hat also bei mir in std::string nichts zu suchen.
std::vector wird mit uint64_t gespeichert.Arcoth schrieb:
Nachteil
uint64_t
: Du merkst ohne weiteres nicht dass die Länge zu groß ist. Das Programm wird irgendeinen Schabernack treiben. Sollen wir jedes mal wenn wir deinenuint64_t
einlesen explizit prüfen ob er nicht in einenstd::string::size_type
passt? Sogar wenn der Stream-Operator es für uns tun könnte?Ja. Den Fehlerzustand überprüfen musst du ja auch. Und zu testen ob die Länge zu groß ist ist ja jetzt auch nicht viel komplizierter, oder?
Arcoth schrieb:
Ein Leser deines Codes wird sich fragen warum zum Teufel du
uint64_t
für die Länge verwendest, denn deine Argumentation wird er nie im Leben nachvollziehen könnenWeil es so schwer zu verstehen ist dass mein Dateiformat explizit so große strings erlaubt? Bei deiner Lösung sieht man nur, dass die Länge plattformabhängig sind. Ob das Program mit größeren Längen zurecht kommt dagegen nicht.
SeppJ schrieb:
Dann können auch z.B. 32Bit Programme die Länge der großen Strings einlesen und dann einen Fehler ausgeben statt Mist zu bauen.
Seit wann können 32-Bit Programme nicht erkennen, ob eine Zahl größer oder kleiner ist als eine andere? Wo ist der Unterschied, wenn man da uint32_t oder size_t als Datentyp benutzt? Die Fehlerbehandlung fehlt bei deinem momentanen Code sowieso, aber sie wäre in beiden Fällen immer noch gleich.
Was ist mit 16-Bit Programmen?Sie können den Fehler erkennen, ja. Aber sie haben die Länge nicht und müssen die Verarbeitung daher abbrechen statt genau sagen zu können was das Problem ist und es eventuell einfach zu ignorieren.
16Bit Programme? Nenn mir einen Grund warum ich das berücksichtigen sollte. Und selbst wenn, 16Bit kann genauso 64Bit Zahlen einlesen.SeppJ schrieb:
Ich zitiere noch einmal die Frage, vor der du dich die ganze Zeit drückst:
Alle Probleme wären mit einem Schlag gelöst, wenn size_t statt einem anderen Typen genommen würde. Eine einzige Änderung an einer einzigen Stelle, der sonstige Code wäre identisch. Wieso diese Gegenwehr?
Nenne einen Grund, nicht immer size_t zu nehmen. Einen einzigen! Du hast 0 Nachteile durch size_t, der Code ist identisch! Bei allen anderen Typen hast du eine künstliche Unportabilität und/oder Grenze eingebaut. "inkonsistent", "mag ich nicht", "niemand braucht das", sind alles nur Strohmannargumente. Wo ist der sachliche Grund, nicht size_t zu nutzen?
Konsistenz.
Sies doch mal von der anderen Seite: Du hast ein Dateiformat in dem Zahlen vorkommen deren Bitbreite unbekannt ist. Wenn du diese Zahlen mit plattformabhängiger Größe einliest, dann kannst du nicht sicherstellen dass sie eingelesen werden können. Du kannst höchstens sagen dass das Einlesen fehlgeschlagen ist. Während ich mit meinem Ansatz die Länge noch einlesen kann, und die Verarbeitung danach weiterführen, wenn ich das will. Das geht bei dir ja wohl nicht.
-
Ja. Den Fehlerzustand überprüfen musst du ja auch.
Ja, und zwar in beiden Fällen (ich hoffe, du überprüfst den Fehlerzustand des Streams bevor du mit der Länge zu arbeiten anfängst?). Bei deinem Scheiß muss ich zusätzlich die Länge überprüfen bevor ich zu einem
size_t
konvertiere, und das ist redundant und nervig.Weil es so schwer zu verstehen ist dass mein Dateiformat explizit so große strings erlaubt?
Es erlaubt gar nichts.
size_t
(std::allocator<>::size_type
) auf der Leseplatform muss 8 Byte groß sein, sonst kannste einen solchen String nicht in einem Stück extrahieren und speichern, weder mitstring
noch mitnew[]
.Konsistenz.
Seit wann kompensiert deine heißgeliebte "Konsistenz" den anderen Ballast!?
Es ist konsistent, die Länge auch binär zu serialisieren? Sollen vielleicht Gürtel aus demselben Stoff wie Hosen gemacht werden, weil das konsistent zu den Hosen ist? inb4 not comparableWarum sollte binäres Schreiben von Integern nicht portabel lösbar sein?
Es ist portabel lösbar, wenn man die Endianness berücksichtigt. Vorteile? Keine signifikanten.
Aber sie haben die Länge nicht und müssen die Verarbeitung daher abbrechen statt genau sagen zu können was das Problem ist
Falsch.
size_t
wird aufstd::numeric_limits<size_t>::max()
gesetzt wenn die Länge zu groß ist. Die genaue Länge brauchen wir eh nicht, das Programm wird nicht weiter arbeiten können wenn die Daten nicht vollständig eingelesen werden können. Hätten wir Strings nutzen wollen/sollen die kleiner als 4GiB groß sind hätten wir sie auch so serialisiert.und die Verarbeitung danach weiterführen, wenn ich das will.
Was du natürlich niemals tun würdest, diese Möglichkeit existiert nur um sie hier als zusätzliche Option erwähnen zu können. Und falls wir das wollen würden, also den String separat in mehrere einzulesen falls die Länge zu groß ist, könnten wir immer noch im Stream zurückgehen und die Länge in einen
uint64_t
einlesen. Den entsprechenden Code leiten wir mit__builtin_unreachable
ein., dann kannst du nicht sicherstellen dass sie eingelesen werden können
Nein, aber wie wir bereits mehrfach erklärt habe... ach, lassen wirs.
Wenn du das als Nachteil anführst musst du als Gegenargument aber auch die bessere Performance akzeptieren.
Das hier ist kein Spiel nach Punkten. Die zwei Millisekunden die wir "langsamer sind" um dafür sauberen, lesbaren und portablen Code zu haben gönnen wir uns.
-
SeppJ schrieb:
Zwei Fehler:
-Vorteile formatierter IO ist nicht nur Menschenlesbarkeit. Ein Hauptvorteil ist Portabilität.Wie schon gesagt, ich sehe absolut nicht, wo man hier weniger Portabilitaet mit binaerer IO hat. Man muss sich bei beidem auf ein Format einigen. Bei formatierter IO gibt es Dinge wie Encoding, bei binaerer IO eben die Groesse der Typen. Endianess ist kein Problem, man kann Integer Endianess-unabhaengig lesen und schreiben ohne irgendwelche ifs.
SeppJ schrieb:
-Ich habe keine Ahnung, wieso du hier Zeichen escapen willst beim String. Es geht schon um binäre Speicherung des Strings. Es geht darum wie du die Länge mitbekommst. Da gibt es eben zwei Methoden, eine unportabel (und meinetwegen 3 µs schneller) und eine portabel.
Warum willst du ein lesbares File, aber einen binaeren String? Wenn da in dem File steht
14|k3?9 ??} ke?9?
dann ist das absolut nicht lesbar. (Ersetze '?' durch ein nicht druckbares Zeichen deiner Wahl)
Hat man hingegen"k3\x009\n\x01\x02}\nke\x039\x04"
dann ist das sehr schoen lesbar. Und mit Editieren fange ich garnicht erst an.
-
Arcoth schrieb:
Ja, und zwar in beiden Fällen (ich hoffe, du überprüfst den Fehlerzustand des Streams bevor du mit der Länge zu arbeiten anfängst?). Bei deinem Scheiß muss ich zusätzlich die Länge überprüfen bevor ich zu einem
size_t
konvertiere, und das ist redundant und nervig.Ja, so eine zusätzliche Bedingung in nem if ist schon extrem schwer...
Arcoth schrieb:
Es erlaubt gar nichts.
size_t
(std::allocator<>::size_type
) auf der Leseplatform muss 8 Byte groß sein, sonst kannste einen solchen String nicht in einem Stück extrahieren und speichern, weder mitstring
noch mitnew[]
.Darum gehts doch gar nicht.
Du musst unterscheiden zwischen dem Dateiformat und dem Program.Arcoth schrieb:
Konsistenz.
Seit wann kompensiert deine heißgeliebte "Konsistenz" den anderen Ballast!?
Es ist konsistent, die Länge auch binär zu serialisieren? Sollen vielleicht Gürtel aus demselben Stoff wie Hosen gemacht werden, weil das konsistent zu den Hosen ist? inb4 not comparableWenn du schon Vergleiche willst dann bitte wenigsten einen der Sinn macht. Was spricht gegen binär ? Außer dass man einmal etwas mehr Code hat. Dank Abstraktion wird man dem nie wieder begegnen.
Letztlich sieht der Code hinter den stream Routinen die dir die Zahlen in Text umwandeln nicht schöner aus. Oder ist dieser Code auch super unsauber und unportabel ?Arcoth schrieb:
Warum sollte binäres Schreiben von Integern nicht portabel lösbar sein?
Es ist portabel lösbar, wenn man die Endianness berücksichtigt. Vorteile? Keine signifikanten.
Es ging darum, dass "Portabilität" für formatted IO nur ein Pseudoargument ist.
Arcoth schrieb:
Aber sie haben die Länge nicht und müssen die Verarbeitung daher abbrechen statt genau sagen zu können was das Problem ist
Falsch.
size_t
wird aufstd::numeric_limits<size_t>::max()
gesetzt wenn die Länge zu groß ist. Die genaue Länge brauchen wir eh nicht, das Programm wird nicht weiter arbeiten können wenn die Daten nicht vollständig eingelesen werden können.Nur wenn dein Programm total Fehlerintolerant ist. Man kann den zu großen string überspringen und weiterarbeiten. Allerdings nur wenn man die exakte Länge kennt!
Arcoth schrieb:
Hätten wir Strings nutzen wollen/sollen die kleiner als 4GiB groß sind hätten wir sie auch so serialisiert.
Bitte was ?
Arcoth schrieb:
und die Verarbeitung danach weiterführen, wenn ich das will.
Was du natürlich niemals tun würdest, diese Möglichkeit existiert nur um sie hier als zusätzliche Option erwähnen zu können. Und falls wir das wollen würden, also den String separat in mehrere einzulesen falls die Länge zu groß ist, könnten wir immer noch im Stream zurückgehen und die Länge in einen
uint64_t
einlesen. Den entsprechenden Code leiten wir mit__builtin_unreachable
ein.Das ist wie mit strings größer als 4GB, braucht man eigentlich nicht, kann man sich aber offen halten. Vorallem dann wenn es keine Nachteile gibt. Außer natürlich der schrecklich unsauberen weiteren Bedingung.
Arcoth schrieb:
Wenn du das als Nachteil anführst musst du als Gegenargument aber auch die bessere Performance akzeptieren.
Das hier ist kein Spiel nach Punkten. Die zwei Millisekunden die wir "langsamer sind" um dafür sauberen, lesbaren und portablen Code zu haben gönnen wir uns.
Es ging darum, dass "Portabilität" für formatted IO nur ein Pseudoargument ist.
-
Hey Leute , bleibt mal aufn Teppich.
Ich wollt nur wissen wie ich´s am besten machen soll.Und ausser Kellerautomat und DarkShadwo hat sich keiner für mich besonders nützlich zu Wort gemeldet.
Also würd ich vorschlagen veröffentlicht doch dann eure Lösungen, oder macht den Thread zu.
-
Noch eine Frage zum code auf der ersten Seite.:
Habe jetzt beide Varianten gefunden, static_cast und reinterpret_cast.
Welches ist für diesen Fall vorzuziehen.
-
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;
Auch dazu hab ich noch eine (hoffentlich abschließende Frage). Rausgeschrieben wird ja jetzt "Formatiert" und eingelesen "Binary? ". Sollte man das dann nicht gleich handhaben und quasi auch formatiert einlesen? Wäre das dann mit getline ?
-
beg_offl schrieb:
Auch dazu hab ich noch eine (hoffentlich abschließende Frage). Rausgeschrieben wird ja jetzt "Formatiert" und eingelesen "Binary? ". Sollte man das dann nicht gleich handhaben und quasi auch formatiert einlesen? Wäre das dann mit getline ?
Was ist denn der Unterschied, ob du einen String mit << in den Stream schiebst oder mit write? Keiner.
getline ist ziemlich schlecht hier, das ganze Theater hier ist doch nur deshalb gemacht, weil getline nicht passt. Was würde denn passieren, wenn der String ein Trennzeichen enthält?
-
Ja, getline funktioniert mir nicht wirklich habe mal folgendes probiert:
void read_f(){ std::cout << "\nWelcome to read form\n"; std::ifstream datei("test_form.txt", std::ios_base::in); for (int i = 0; i < 3; i++){ size_t len = 0; datei >> len; std::cout << "\nLEN : " << len << "\n"; datei.ignore(); std::vector<char>zeile(len); datei.getline(&zeile[0], len); std::string out(zeile.begin(), zeile.end() ); std::cout << "HERE" << out; out.clear(); } datei.close(); }
Es wird davor 3 x mit datei << len << inhalt in die Datei geschrieben, kann aber nur 1x auslesen. Das liegt an dem Trennzeichen und getline oder? Dachte erst der "Dateizeiger" wandert nicht richtig mit..
-
Noch ne Frage :
ignore() ignoriert einfach das nächste Zeichen oder ?
hatte bis jetzt nur xy.ignore(Zeichenanzahl, "\n"), benutzt...
-
Schau dir die Default-Argumente an.