write int in file

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Python93
User
Beiträge: 36
Registriert: Mittwoch 13. Juni 2012, 07:50

Hallo miteinander.
Kurze Frage... Ich habe die Aufgabe eine Datei binär Byte-für-Byte zu füllen. Mit einer Variable die ihren Integer-Wert pro Schleifendurchlauf verändert.

Frage 1:
Kann ich Integer Zahlen überhaupt binär als 1 Byte in eine Datei schreiben, oder muss ich sie z,b mit hex() umwandeln??

Ich habe mich schon im Internet schlau gemacht, es gibt einen anderen Weg, wenn man die Zahl mit hex() in einen String umwandelt.
Dann kann man es mit

Code: Alles auswählen

file.write("\x...")
fest kodiert hineinschreiben.
Jedoch gehen da nur feste Werte bsp.

Code: Alles auswählen

file.write("\x2a")
Was ich aber brauche, um auf meine Ausgangssituation zurück zu kommen, ist ein Weg wie ich die Variable in den Befehl

Code: Alles auswählen

file.write("\x...")
reinbekomme.

Frage 2:
Könntet ihr mir bitte einen Tipp geben?

Ich hoffe es ist verständlich was ich meine und brauche...
Ich benutze:
- Python 2.7
- Windows XP
deets

Die Funktion die du suchst heisst "chr":

Code: Alles auswählen

>>> chr(3)
'\x03'
Achtung: hex hat mit all dem nix zu tun. Das wandelt eine Zahl in einen String mit der Hexadezimaldarstellung der Zahl um. Das hat aber nix mit binaeren Bytes zu tun. Kann man auch ganz einfach sehen:

Code: Alles auswählen

>>> "\x03" == hex(3)
False
Python93
User
Beiträge: 36
Registriert: Mittwoch 13. Juni 2012, 07:50

Danke sehr deets! :) Das hat geholfen.
Ich benutze:
- Python 2.7
- Windows XP
Python93
User
Beiträge: 36
Registriert: Mittwoch 13. Juni 2012, 07:50

@ deets, ich hätte da noch eine kleine Frage...

Ist das Ergebnis von char() immer ein Byte groß??
Ich benutze:
- Python 2.7
- Windows XP
Python93
User
Beiträge: 36
Registriert: Mittwoch 13. Juni 2012, 07:50

Vielen Dank, dann ist das wirklich 100%ig was ich brauche!!! :) :D
Ich benutze:
- Python 2.7
- Windows XP
Python93
User
Beiträge: 36
Registriert: Mittwoch 13. Juni 2012, 07:50

Code: Alles auswählen

chr(1)
>>> '\x01'
Passt soweit ja. Aber wenn ich 10 habe:

Code: Alles auswählen

chr(10)
>>> '\n'
Warum kommt da z,b. nicht "\x10" oder wenn ich 9 habe:

Code: Alles auswählen

chr(9)
>>> '\t'
anstatt '\x09'...???
Könnte mir das noch einer erklären bitte?
Ich benutze:
- Python 2.7
- Windows XP
Benutzeravatar
snafu
User
Beiträge: 6731
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

Weil es nicht darum geht, einfach immer `\x` vor eine Zahl zu schreiben... ^^

Guckst du ASCII-Tabelle.
BlackJack

@Python93: Weil die Bytewerte 9 und 10 für das Tabulatorzeichen und den Zeilenvorschub stehen und es lesbarer/verständlicher ist dort die enstsprechenden Escape-Sequenzen anzuzeigen, die man auch literal eingeben kann.
Benutzeravatar
/me
User
Beiträge: 3554
Registriert: Donnerstag 25. Juni 2009, 14:40
Wohnort: Bonn

Python93 hat geschrieben:

Code: Alles auswählen

chr(10)
>>> '\n'
Warum kommt da z,b. nicht "\x10"
\x10 wäre es ohnehin nicht, da die Angaben hexadezimal sind. Es müsste folglich \x0a sein. Das wiederum ist tatsächlich identisch mit \n.

Code: Alles auswählen

>>> '\n' == '\x0a'
True
\n = newline
\r = carriage return
\t = tabulator
Diese Kürzel sind so verbreitet, dass sie direkt angezeigt werden und nicht hexadezimal codiert werden
Python93
User
Beiträge: 36
Registriert: Mittwoch 13. Juni 2012, 07:50

Aber als Wert funktionieren sie trotzdem? Also wenn ich mit

Code: Alles auswählen

chr(10)
umwandel und in eine Datei schreibe, weiß die Datei dann dass an der Stelle der Wert 10 ist und nicht einfach ne neue Zeile?
Ich benutze:
- Python 2.7
- Windows XP
Benutzeravatar
snafu
User
Beiträge: 6731
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

Oder vielleicht noch etwas deutlicher: Wenn es in dem verwendeten Zeichensatz ein darstellbares Zeichen für den Bytewert gibt (ich verweise auf die zuvor gepostete Tabelle), dann wird dieses Zeichen angezeigt. Der (hexdezimal ausgedrückte) Bytewert bleibt aber natürlich bestehen. Derlei Darstellungen sind ja nichts weiter als eine "kontextabhängige" (gemeint ist der Zeichensatz) Interpretation des Bytewerts. Das hatten wir aber auch schon ca eine Million Mal hier im Forum...
Benutzeravatar
snafu
User
Beiträge: 6731
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

Python93 hat geschrieben:Aber als Wert funktionieren sie trotzdem? Also wenn ich mit

Code: Alles auswählen

chr(10)
umwandel und in eine Datei schreibe, weiß die Datei dann dass an der Stelle der Wert 10 ist und nicht einfach ne neue Zeile?
Die Datei weiß gar nichts. Sie speichert den Wert nur stumpf ab. Was ein Terminalfenster oder sonstiges Ausgabemedium damit anstellt, ist nicht mehr Sache der Datei.
Zuletzt geändert von snafu am Mittwoch 4. Juli 2012, 09:45, insgesamt 1-mal geändert.
Python93
User
Beiträge: 36
Registriert: Mittwoch 13. Juni 2012, 07:50

Achso, ok verstanden.
snafu hat geschrieben:Das hatten wir aber auch schon ca eine Million Malh hier im Forum...
Kann sein, es hat sich nur angeboten im Kontext hier weiterzufragen. Danke für die Erklärung.

Lg Python93
Ich benutze:
- Python 2.7
- Windows XP
Benutzeravatar
snafu
User
Beiträge: 6731
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

Hier kann man übrigens nochmal genauer sehen, dass im Grunde alles nur Interpretationssache ist:

Code: Alles auswählen

>>> 0x4d
77
>>> '\x4d'
'M'
Es geht beide Male um den Dezimalwert 77. Bei der ersten Variante, wird er in hexadezimaler Form angegeben, sodass seine *Entsprechung* (dezimal) als Integer ausgegeben wird. In der zweiten Variante wird die besondere Stringform (`\x`) angegeben, sodass für den daran anschließenden hexadezimalen Wert (`4d`) das passende Zeichen rausgesucht werden kann.

Man kann das auch noch weiter fassen:

Code: Alles auswählen

>>> '\x80'
'\x80'
>>> '\x80'.decode('windows-1252')
u'\u20ac'
>>> print '\x80'.decode('windows-1252')
€
Der Hex-Wert 80 (nicht mit Dezimal verwechseln) hat im ASCII-Zeichensatz keine Entsprechung. Daher wird er ohne "Ersetzung", quasi in "Reinform" angezeigt. Bei der Verwendung eines Unicode-Zeichensatzes benutzt Python 2.x (Python3 funktioniert anders) stattdessen eine entsprechende Unicode-Zeichenkette (`u'\u20ac'`). Beachte, dass diese Darstellung immer noch genau einem Zeichen entspricht - "speichertechnisch" jedoch nicht mehr einem Byte, sondern jetzt 2 Bytes.¹ Schickt man diese schließlich an den Ausgabestrom des Terminals (mittels `print`), dann erkennt man, dass dieses "kryptische Ding" durch den Zeichensatz als Euro-Zeichen interpretiert wird. :)

Aber das nur nebenbei. Möglicherweise verstehst du Thematik damit ein bißchen besser... ;)

̣̣_____

¹ Um korrekt zu bleiben: Bereits das Speichern des Hex-Wertes 80 verbraucht 2 Bytes, weil es von der Größe her halt nicht mehr in ein Byte reinpasst. Nicht, dass es sich so anhört, als käme der Zusatzverbrauch durch das Encoding...
jerch
User
Beiträge: 1669
Registriert: Mittwoch 4. März 2009, 14:19

snafu hat geschrieben:¹ Um korrekt zu bleiben: Bereits das Speichern des Hex-Wertes 80 verbraucht 2 Bytes, weil es von der Größe her halt nicht mehr in ein Byte reinpasst. Nicht, dass es sich so anhört, als käme der Zusatzverbrauch durch das Encoding...
Wie kommst Du darauf? Vermutlich verwechselst Du 7bit ASCII vs 8bit encoding mit single vs multibyte encodings. Ein Byte hat immernoch 8 Bit, daher passt da alles bis FF rein.
BlackJack

Wenn wir *ganz* genau sein wollen, dann hat ein Byte so viele Bits wie das für die entsprechende Plattform festgelegt ist. Das ist heutzutage bei den allermeisten Systemen 8 Bits, aber das muss nicht zwingend so sein. Deshalb wird bei Binärprotokollen in der Regel nicht der Begriff „Byte” sondern „Oktett” (engl. „octet”) in der Spezifikation für 8-Bit-Einheiten verwenden. :-)
jerch
User
Beiträge: 1669
Registriert: Mittwoch 4. März 2009, 14:19

@BlackJack:
Hehe jup, ich war stillschweigend von der PC-Architektur ausgegangen. Im Deutschen wäre Bit wahrscheinlich eine Biffer (binäre Ziffer) oder Belle (für Stelle im Dualsystem) und ein Byte, hmm keine Ahnung, vllt. ein Bötzelchen oder Batzen, wobei das entsprechend der Plattformfestlegung viele Biffern enthält :P
BlackJack

Batzen zu acht Biffern gefällt mir irgendwie. :-D
Benutzeravatar
snafu
User
Beiträge: 6731
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

jerch hat geschrieben:
snafu hat geschrieben:¹ Um korrekt zu bleiben: Bereits das Speichern des Hex-Wertes 80 verbraucht 2 Bytes, weil es von der Größe her halt nicht mehr in ein Byte reinpasst. Nicht, dass es sich so anhört, als käme der Zusatzverbrauch durch das Encoding...
Wie kommst Du darauf? Vermutlich verwechselst Du 7bit ASCII vs 8bit encoding mit single vs multibyte encodings. Ein Byte hat immernoch 8 Bit, daher passt da alles bis FF rein.
Stimmt... :oops:
Antworten