Strukturen lesen funktioniert nicht
-
Wieso bin ich hier im falschen Forum? Es funktioniert ja das einlesen der Struktur in !!!C++!!! nicht... der c# auschnitt dient ausschließlich zum Verständnis, weil ich die Maperstellung in c# schreiben werde, weil die grafische komponente beim map creator wegfallen wird.
XmlSerializer bringt mir nicht viel da ich die Daten Binary halten will, weil sie dann auch weniger Speicherplatz benötigen als wenn ich 3000 Tags mit Attributes habe...
mfg Hurraa
-
Dein Problem ist Padding. Zum Beispiel deine
mapcellStruktur hat nicht 3 Bytes, wie du es wahrscheinlich erwarten würdest, sondern ein paar mehr Bytes. Dies wird gemacht, damit der Prozessor besser damit arbeiten kann, vor allem auch schneller. Selbes gilt auch bei Arrays und anderen Strukturen oder Klassen.Die beste Lösung bei sowas ist, dass du nicht eine Struktur einliest, sondern jeweils die einzelnen Daten. Also zuerst ein
short, dann einchar, daraus machst du einemapcell, dann wieder einshort, wieder einchar, wieder einemapcellzusammenstellen, usw. bis du einmapblockhast, usw. bist du allemapblockhast.Beim Einlesen von
shortsolltest du zudem auf die Bytereihenfolge achten. Stichwort: Big-Endian, Little-Endian.Grüssli
-
Dravere schrieb:
...
Die beste Lösung bei sowas ist, dass du nicht eine Struktur einliest, sondern jeweils die einzelnen Daten. Also zuerst einshort, dann einchar, daraus machst du einemapcell, dann wieder einshort, wieder einchar, wieder einemapcellzusammenstellen, usw. bis du einmapblockhast, usw. bist du allemapblockhast.Beim Einlesen von
shortsolltest du zudem auf die Bytereihenfolge achten. Stichwort: Big-Endian, Little-Endian.Grüssli
Nur als Nebenbemerkung: Man DARF Daten auch lesbar in Dateien schreiben (und lesen) ... das ist weder verboten noch per se zu langsam, hat aber eine Menge Vorteile (gerade bzgl. Plattformunabhängigkeit, Versionierung und Debugging).
Gruß,
Simon2.
-
Danke für die Antworten. Könntet ihr mir noch Big-Endian und Little-Endian erläutern?
mfg Hurraa
-
Hurraa schrieb:
Danke für die Antworten. Könntet ihr mir noch Big-Endian und Little-Endian erläutern?
das betrifft dich nur, wenn du dein prog für unterschiedliche maschinen bauen willst. wenn du bei normalen pcs bleiben willst, isses egal, denn alle normalen pcs haben die selbe endianess.
-
Hm eine letzte Frage habe ich noch:
Wie sieht nun das Einlesen von den einzelnen Daten aus?
Weil mein folgender code funktioniert nicht:mapcell mc; ifstream in("test.map",ios::binary); in >> mc.texid; in >> mc.z; ... in.close();Selbst die ersten Zahlen sind weit außerhalb des möglichen wertebereichs wie -1239540 oder 129054...
Habt ihr vielleicht ein gutes Tutorial, das io WIRKLICH abdeckt?
mfg Hurraa
-
Hi,
nochmal mein Tipp:
Hurraa schrieb:
...
ifstream in("test.map",ios::binary);...
=>
ifstream in("test.map");(inkl. der cpp-Tags)
... natürlich auch beim Schreiben.Gruß,
Simon2.
-
@Hurraa,
Überoperator >>undoperator <<liest und schreibt man normalerweise nur Text. Wenn du binär lesen und schreiben willst, dann musst du die Methodenwriteundreadnehmen. Wie du es vorhin auch gemacht hast.@Simon2,
Wenn er die Dateien binär bearbeiten will, dann iststd::ios::binarydringend erforderlich.Grüssli
-
Dravere schrieb:
...Wenn er die Dateien binär bearbeiten will, ...
Klar - mein Vorschlag zielte ja auch genau darauf ab, dass er sie NICHT binär bearbeiten sollte.
Hurraa schrieb:
...
XmlSerializer bringt mir nicht viel da ich die Daten Binary halten will, weil sie dann auch weniger Speicherplatz benötigen als wenn ich 3000 Tags mit Attributes habe...Da würde ich sehr genau prüfen, ob dieses Argument angesichts der Nachteile (frickeliges, sehr plattform- und Compilerababhängiges Lesen und Schreiben, komplizierte Fehlersuche, ...) wirklich zieht. Natürlich gibt es Anwendungsfälle, bei denen es auf jedes Terabyte Plattenplatz ankommt - aber in der Praxis sind es seeehr viel weniger als der geneigte Entwickler es meint.
Oder sagen wir mal so: So, wie es bislang angefangen ist, wird es vermutlich noch längere Zeit weitergehen und immer wieder kommen ... Zeit und Nerven, die man evtl. an anderen Ecken des Programms besser brauchen kann.
Wenn man natürlich Daten von außen angeliefert bekommt, hat man halt keine Wahl ... aber da würde ich sehr genau auf eine saubere und vom "Fachcode" getrennte Einleseschnittstelle achten.
Gruß,
Simon2.
-
Simon2 schrieb:
Klar - mein Vorschlag zielte ja auch genau darauf ab, dass er sie NICHT binär bearbeiten sollte.
Was habt ihr eigentlich alle gegen binäre Formate? Es gibt Einsatzzwecke für beides und Vor- und Nachteile hat es oft bei beiden in etwa gleich viele.
Grüssli
-
Ich persönlich benutze meist einfache Textdateien, da
- die Handhabung relativ einfach ist und meiner Ansicht nach weniger Fehlerquellen beinhaltet
- ich die Dateien auch mit dem Text-Editor anschauen und verändern kann (finde ich teilweise noch praktisch)
- bei mir semantisches Schreiben völlig ausreicht und Speicherverbrauch bzw. 1:1-binäres Schreiben nicht relevant ist
- die Dateien auch weiterverwendet werden können, sollte man etwas an seinen Strukturen ändern; Anpassungen der Dateien finde ich transparenter
- man keine Rücksicht auf compilerabhängige Dinge wie Padding, VTable etc. nehmen muss
- ich den objektorientierten
operator<<bzw.operator>>gleich dazu nutzen kann, um ganze Klassen zu lesen oder schreiben
Aber wie angetönt hat binäres Schreiben/Lesen genauso seine Vorteile, ich wollte nur mal meine Sichtweise präsentieren.

-
Nexus schrieb:
Ich persönlich benutze meist einfache Textdateien, da...
geht mir auch so.
und im entwurf lasse ich von vorn herein immer offen, noch zusätzlich einen BinaryWriter/Reader anzubieten, wenn mal zeit bleibt und sich bedarf andeutet, aber nötig isses eigentlich nie. hihi.
-
Dravere schrieb:
...
Was habt ihr eigentlich alle gegen binäre Formate? ...Ich habe gegen sie, dass sie üblicherweise die erste und einzige Idee von Anfängern ist, die sich mühsam die Finger damit brechen, das Forum mit Fragen überschwemmen und am Ende darüber klagen, wie schrecklich doch C++ ist und die Welt mit grauenhaftem und unportablem Code überziehen - und das ganze vollkommen überflüssigerweise.

Gaaaanz großer Schwerpunkt bei "Anfänger".
Gruß,
Simon2.
-
Nexus schrieb:
die Handhabung relativ einfach ist und meiner Ansicht nach weniger Fehlerquellen beinhaltet
Gilt auch für ein gut dokumentiertes Binärformate

Nexus schrieb:
ich die Dateien auch mit dem Text-Editor anschauen und verändern kann (finde ich teilweise noch praktisch)
Ein gut dokumentiertes Binärformat kann man mit einem Hexeditor anschauen und verändern. Wobei ich oft Binärformate bewusst wähle, damit man sie nicht so einfach verändern kann. Vor allem macht es auch nicht immer Sinn, dass man im File herumpfuschen können soll

Nexus schrieb:
bei mir semantisches Schreiben völlig ausreicht und Speicherverbrauch bzw. 1:1-binäres Schreiben nicht relevant ist
1:1 binäres Schreiben wäre ein fataler Fehler. In einem Binärformat kannst du genauso semantisch schreiben. Du musst nur entsprechende Strukturen definieren, halt ein Format erfinden oder ein bereits bekanntes nehmen.
Ich habe erst letztens ein Binärformat erfunden. Hat eine Jumptable, erlaubt verschiedene Datengrössen, hat rohe Daten und Elementdaten. Man kann alles schön in Elemente aufteilen und dank der Jumptable kann man gleich an die richtige Stelle im File springen, wenn man nur gewisse Elemente lesen möchte.
Probier mal eine Jumptable in einem Textfile zu machen

Nexus schrieb:
die Dateien auch weiterverwendet werden können, sollte man etwas an seinen Strukturen ändern; Anpassungen der Dateien finde ich transparenter
Ist auch absolut kein Problem bei einem Binärformat. Natürlich nur dann, wenn du eine entsprechende Dokumentation hast und das Format entsprechend aufgebaut ist, dass es dies erlaubt. 1:1 schreiben wäre natürlich völlig verkehrt

Nexus schrieb:
man keine Rücksicht auf compilerabhängige Dinge wie Padding, VTable etc. nehmen muss
Wenn du nicht 1:1 schreibst und alles korrekt dokumentiert hast, dann ist das auch beim binären Schreiben kein Problem. Vor allem solltest du dann aber nicht ganze
structprobieren zu schreiben, sondern wie bei einem Textfile auch, Element für Element.Nexus schrieb:
ich den objektorientierten
operator<<bzw.operator>>gleich dazu nutzen kann, um ganze Klassen zu lesen oder schreibenKannst du auch verwenden, musst dir nur einen Binarystream erstellen. Sowas geht relativ einfach und kann man wiederverwenden

Allerdings bevorzuge ich meinstens sowieso nicht die Streamoperatoren, auch nicht bei Text. Bzw. ich verwende sie oft nur für Debugausgaben.Ich setze die Ausgabe lieber in eine eigene Klasse, welche dann weitere Dinge steuern kann. Die Streamoperatoren sind mir oft zu simpel.
@Simon2,
Ok, da kann man nur zustimmen. Den Fehler hatte ich als Anfänger auch gemacht
Wobei ich mich zwar aufgeregt und die Finger gebrochen habe, aber trotzdem weiter von C++ fasziniert war und mich weiterentwickelt habe
Grüssli
-
Dravere schrieb:
...
1:1 binäres Schreiben wäre ein fataler Fehler. ...Ist aber genau das, was (gerade Anfänger) zu 99,99% meinen und machen.
Ansonsten gibt es auch kaum noch Unterschiede zwischen einem "Serialisierungsformat", das nur druckbare Zeichen verwendet und einem, das das nicht tut....Das Wesentliche meiner Kritik an "Binärschreiben" zielt genau auf das "1:1-Format".
(OK, wenn man in jedem Txt-Editor lesen/bearbeiten kann, ist das nett, aber längst nicht so kritisch wie die anderen Aspekte)Gruß,
Simon2.