Du bist nicht angemeldet.

Stilllegung des Forums
Das Forum wurde am 05.06.2023 nach über 20 Jahren stillgelegt (weitere Informationen und ein kleiner Rückblick).
Registrierungen, Anmeldungen und Postings sind nicht mehr möglich. Öffentliche Inhalte sind weiterhin zugänglich.
Das Team von spieleprogrammierer.de bedankt sich bei der Community für die vielen schönen Jahre.
Wenn du eine deutschsprachige Spieleentwickler-Community suchst, schau doch mal im Discord und auf ZFX vorbei!

Werbeanzeige

dot

Supermoderator

Beiträge: 9 757

Wohnort: Graz

  • Private Nachricht senden

21

16.12.2010, 10:40

Edit: Bei der Austauschbarkeit von Bibliotheken zwischen Kompilern geb ich dir dann recht. Offensichtlich kam ich noch nie in diese Lage, sonst hätte ich diesen Punkt bereits auch schon als schmerhaft empfunden.

Ja, natürlich ist das oft (und wahrscheinlich auch in seinem Fall) kein Problem, ich wollte nur explizit darauf hinweisen um zu verhinden dass es vielleicht mal zu einem wird ;)

22

16.12.2010, 17:38

Okay, danke für eure Antworten :)
Ich denke allerdings, dass meine Funktionen und Klassen nicht so toll sind, dass sie jemals jemand anders benutzen will^^
Geschweige denn, dass jemand mit Mac oder Linux auf die idee kommt meine dll zu nutzen. Wenn es jemand nutzen würde, dann vllt. einer meiner Freunde.

Mein Problem ist jetzt aber leider noch nicht ganz weg.
Es scheint irgendwo an meinem Code zu liegen, aber ich komme nicht drauf.

Wenn ich die Daten mit dem "<<" Operator an den Stream übergebe klappt alles wie es soll.

Also so:

C-/C++-Quelltext

1
2
3
4
std::ofstream output; 
output.open ("Datei.txt",std::ios::app); 
output << "Irgendwas"; 
output.close ();



Wenn ich es jedoch so wie oben mache kann ich keine Daten in binär-Form schreiben, was ja durchaus manchmal praktisch ist.
Das geht meines Wissens nur mit output.write()

Wenn ich jetzt allerdings folgendes schreibe:

C-/C++-Quelltext

1
2
3
4
output.open ("Datei.txt", std::ios::binary); 
std::string Text = "hi";
output.write (Text.c_str(), Text.size()); 
output.close ();


Und es dann wieder mit einem ifstream direkt danach auslese kommt nichts richtiges raus, nur kryptische Zeichen. (Beim ifstream ist natürlich auch das Flag ios::binray gesetzt).
Es funktioniert übrigens auch nicht, wenn ich .write() ohne ios::binary nutzt.

Kann mir jemand verraten wie das richtig geht?

lg chaia

23

16.12.2010, 18:46

Wie liest du den Text denn wieder ein?

24

16.12.2010, 19:32

Ich versuche es auf 2 Wegen:

1. Ich öffne die txt Datei einfach mit dem Editor und sehe dann was da steht. Klappt bei der 1. Methode wunderbar und hat mich auch sonst nie im Stich gelassen.
2. Sieht folgendermaßen aus:

C-/C++-Quelltext

1
2
3
4
5
std::ifstream input ("Datei.txt", std::ios::binary); 
std::string Textout; 
input >> Textout;
input.close (); 
std::cout << Textout << std::endl;


Und die sollte meiner Meinung nach funktionieren....
Es wird auch was ausgegeben, sieht allerdings fast genau gleich aus, wie wenn ich es mit dem Editor anschaue. Nur dass die Zeichen etwas verzerrt sind, wie für die Konsole teils üblich.

EDIT: Meine 1. Art den text wieder einzulesen kann eigentlich nicht funktionieren, da es ja binary ist. Jedoch sehe ich teils auch Buchstaben. Bin mir also nicht sicher, ob binary überhaupt funktioniert.

lg chaia

25

17.12.2010, 20:51

weiß niemand wo mein Fehler ist oder wollt ihr, dass ich selbst drauf komme?^^
Kann doch nicht so schwer sein..

26

18.12.2010, 10:52

Also Chaia* du könntest die Datei z.B. einmal unter einem Hex-Editor anschaun, und den Inhalt dort überprüfen.
Zu 2. Wie wäre es, wenn du erst nen char* ausliest ;) Du schreibst chars rein, und liest einen std::string aus, ich bin mir nicht sicher, ob das so gut klappt. Probiers mal, wenn du wieder nur ein char-array ausliest ;)

dot

Supermoderator

Beiträge: 9 757

Wohnort: Graz

  • Private Nachricht senden

27

18.12.2010, 11:01

Ich versteh ehrlich gesagt nicht ganz wo dein Problem ist. Außerdem find ich es etwas ungewöhnlich dass du die << und >> Operatoren auf Binärdateien verwendest.

28

18.12.2010, 13:08

Mein Problem ist, dass die Ausgabe in eine Datei mir .write () nicht funktioniert.
Weder mit , noch ohne ios::binary. Wenn ich ganz normal etwas reinschreibe ohne irgendwelche Flags kommt nichts gescheites dabei raus. Wenn ich es mit << mache, kann ich die Daten schön mit dem Editor anschauen, mit .write() (ohne binary) geht das nicht.
Ist das allgemein so oder was könnte da los sein?

Wenn es binär Daten wären, dann würde ich .read() benutzen, aber das schreiben mit write() und binary sieht aus wie ohne binary.
Also kurz zusammengefasst:

- .write() funktioniert mit und ohne binary nicht (sieht beides gleich aus im Editor, dabei sollte es zumindest ohne binary lesbar sein)
- mit dem << operator funktioniert das einlesen und manipulieren über den editor wunderbar

dot

Supermoderator

Beiträge: 9 757

Wohnort: Graz

  • Private Nachricht senden

29

18.12.2010, 15:00

Irgendwie hab ich das Gefühl dass dir nicht so 100%ig klar ist was der Unterschied zwischen Binär- und Textmodus ist. Darum vielleicht an dieser Stelle eine kurze Erklärung (erstmal ganz allgemein und komplett unabhängig von C++):
Zunächst gilt es einmal festzuhalten dass eine Datei immer(!) nur ein Haufen Bytes ist. Es kommt immer nur darauf an wie diese Bytes interpretiert werden. Wenn du eine Datei im Editor öffnest dann interpretiert dieser sie als Textdatei, das bedeutet er interpretiert jedes Byte der Datei als Buchstabe und zeigt dann eben für jedes Byte an der entsprechenden Stelle den Buchstaben an der dem jeweiligen Bytewert entspricht. Wenn die Bytes in der Datei keinen Text repräsentieren dann wird einem der Editor natürlich nur unlesbaren "Müll" anzeigen da die einzelnen Bytes dann eben keine Buchstaben repräsentieren sondern etwas anderes. Wenn die Datei zum Beispiel einen 4 Byte langen integer mit dem Wert 926300213 (in Hex 0x37363835) enthält dann wird der Editor dir an dieser Stelle den Text #&$% anzeigen da (nach der ASCII Zeichentabelle) die einzelnen Bytes des int eben diesen Buchstaben entsprechen würden. Das bedeutet aber auch wenn du ein char Array das einen Text enthält in eine Datei schreibst dann wirst du im Editor immer an der entsprechenden Stelle in der Datei den Text sehen, egal ob die Datei im Binär oder Textmodus geschrieben wurde.
Man beachte dass ich hier ständig von Binär- bzw Textmodus rede und nicht von Binär- oder Textdatei. Das hat einen einfachen Grund: Ich will damit unmissverständlich klar machen dass es sich nicht um zwei verschiedene Arten von Dateien handelt sondern lediglich um zwei verschiedene Arten des Dateizugriffes. Es gibt nur eine Art von Datei, nämlich das was (wie eingangs erwähnt) jede Datei ist: Ein Haufen Bytes.
Wo liegt dann nun aber der Unterschied zwischen Binär- und Textmodus? Ganz einfach: Auf verschiedenen Betriebssystemen gibt es historisch bedingt unterschiedliche Standards wie gewisse Dinge wie z.B. Zeilenumbrüche ('\n') gehandhabt werden. Unter Windows beispielweise wird ein Zeilenumbruch durch die Bytesequenz 0xD gefolgt von 0xA (entspricht '\r' gefolgt von '\n', carriage return + line feed wie es früher bei Fernschreibern gemacht wurde) dargestellt während auf Unix basierten Systemen nur 0xA (einfach nur '\n') verwendet wird. Damit man sich nicht ständig um solche betriebssystemspezifischen Feinheiten kümmern muss gibt es den sog. Textmode. Ist eine Datei im Textmodus geöffnet dann wird beim Schreiben automatisch jedes Byte das einem '\n' entspricht in die jeweilige betriebssystemspezifische Repräsentation umgewandelt (unter Windows wird ein '\n' beim Schreiben in die Datei also zu einem '\r' '\n'). Analog dazu wird beim Lesen ebenfalls automatisch von der betriebssystemspezifischen Repräsentation zurück in '\n' umgewandelt (unter Windows wird die Bytefolge '\r' '\n' beim Lesen aus der Datei also zu einem '\n'). Im Binärmodus wird dagegen keine Umwandlung vorgenommen, alles was du liest oder schreibst entspricht 1:1 dem was auch in der Datei steht. Das ist alles.
Der Editor arbeitet natürlich entsprechend der unter Windows üblichen Konvention und zeigt genau dann einen Zeilenumbruch an wenn in der Datei auch ein '\r' '\n' steht. Wenn in der Datei nur ein '\n' steht dann wird er es als Buchstabe interpretieren was, je nach Schriftart, normalerweise einem kleinen Kästchen entspricht. Wenn du schonmal Text im Binärmodus geschrieben hast oder versucht hast eine unter Linux erzeugte Textdatei im Windows Editor zu öffnen wird dir vermutlich aufgefallen sein dass er statt Zeilenumbrüchen einfach nur kleine Kästchen anzeigt. Jetzt kennst du den Grund dafür.

Wo wir nun wissen was genau Text- und Binärmodus sind wollen wir uns anschauen was der Unterschied zwischen read() bzw. write() und dem >> bzw. << Operator ist. Und auch das ist nicht weiter kompliziert: read() und write() lesen bzw. schreiben einfach eine Bytesequenz aus bzw. in eine Datei. Die >> und << Operatoren dagegen machen formatierten Input/Ouput. D.h. sie wandeln was ihnen übergeben wird in eine Textrepräsentation um und schreiben diese in die Datei bzw. lesen eine Textrepräsentation aus einer Datei und wandeln sie in ein entsprechendes Objekt um. Wenn du beispielweise einen int mit dem Wert 201985291 (Hex 0x0C0A0D0B) per << in eine Datei ausgibst so schreibt << nicht direkt die Bytes des int in die Datei sondern erzeugt eine Zeichenfolge die den Wert dieses int repräsentiert und schreibt diese in die Datei. Im konkreten Beispiel landen dann also nicht 4 Bytes mit den Werten 0x0B 0x0D 0x0A 0x0C in der Datei sondern eine Bytesequenz die der Zeichenfolge '2' '0' '1' '9' '8' '5' '2' '9' '1' entspricht. Der >> Operator tut natürlich genau das gleiche nur in die andere Richtung, würde also die Zeichenfolge wieder auslesen und zu einem int mit dem Wert 201985291 machen. Wichtig ist dass all das unabhängig vom Modus in dem die Datei geöffnet wurde gemacht wird. Im Textmodus finden wie bereits besprochen automatische Umwandlungen statt und im Binärmodus nicht, ganz egal ob du mit write(), read(), << oder >> schreibst/liest. Wenn man Gebrauch vom formatierten Input/Output der >> bzw. << Operatoren macht dann tut man dies nur eben meistens genau dann wenn man mit Textdateien arbeitet und wenn man mit Textdateien arbeitet wird man normalerweise den Textmodus benutzen. Wenn man analog dazu keine für Menschen lesbare Form braucht und einfach direkt Daten lesen/schreiben will wird man dies mit read()/write() im Binärmodus tun da die automatischen Umwandlungen des Textmodus dabei unerwünscht sind (würdest du den int mit dem Wert 0x0C0A0D0B von vorhin im Textmodus per write() in die Datei schreiben so würde das dritte Byte, das zufällig einem '\n' entspricht, umgewandelt und am Ende ein komplett anderer Wert in der Datei landen).

Ich hoffe ich hab nun ein wenig Licht ins Dunkel gebracht und bin mir ziemlich sicher dass du mit diesem Wissen in der Lage sein wirst dein Problem zu lösen ;)

Dieser Beitrag wurde bereits 2 mal editiert, zuletzt von »dot« (18.12.2010, 15:08)


30

18.12.2010, 16:17

Oha, danke für die ausführliche Erklärung :thumbsup:
Jetzt ist einiges klar geworden :)
Wäre meiner Meinung ein Eintrag im FAQ wert!

lg chaia

Werbeanzeige