Seite 1 von 2

write int in file

Verfasst: Mittwoch 27. Juni 2012, 13:05
von Python93
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...

Re: write int in file

Verfasst: Mittwoch 27. Juni 2012, 13:22
von 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

Re: write int in file

Verfasst: Mittwoch 27. Juni 2012, 13:33
von Python93
Danke sehr deets! :) Das hat geholfen.

Re: write int in file

Verfasst: Mittwoch 4. Juli 2012, 08:43
von Python93
@ deets, ich hätte da noch eine kleine Frage...

Ist das Ergebnis von char() immer ein Byte groß??

Re: write int in file

Verfasst: Mittwoch 4. Juli 2012, 08:47
von BlackJack
@Python93: Ja.

Re: write int in file

Verfasst: Mittwoch 4. Juli 2012, 08:50
von Python93
Vielen Dank, dann ist das wirklich 100%ig was ich brauche!!! :) :D

Re: write int in file

Verfasst: Mittwoch 4. Juli 2012, 09:00
von Python93

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?

Re: write int in file

Verfasst: Mittwoch 4. Juli 2012, 09:16
von snafu
Weil es nicht darum geht, einfach immer `\x` vor eine Zahl zu schreiben... ^^

Guckst du ASCII-Tabelle.

Re: write int in file

Verfasst: Mittwoch 4. Juli 2012, 09:28
von 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.

Re: write int in file

Verfasst: Mittwoch 4. Juli 2012, 09:30
von /me
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

Re: write int in file

Verfasst: Mittwoch 4. Juli 2012, 09:40
von Python93
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?

Re: write int in file

Verfasst: Mittwoch 4. Juli 2012, 09:41
von snafu
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...

Re: write int in file

Verfasst: Mittwoch 4. Juli 2012, 09:44
von snafu
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.

Re: write int in file

Verfasst: Mittwoch 4. Juli 2012, 09:44
von Python93
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

Re: write int in file

Verfasst: Mittwoch 4. Juli 2012, 10:22
von snafu
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...

Re: write int in file

Verfasst: Mittwoch 4. Juli 2012, 11:41
von jerch
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.

Re: write int in file

Verfasst: Mittwoch 4. Juli 2012, 11:53
von 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. :-)

Re: write int in file

Verfasst: Mittwoch 4. Juli 2012, 12:13
von jerch
@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

Re: write int in file

Verfasst: Mittwoch 4. Juli 2012, 12:29
von BlackJack
Batzen zu acht Biffern gefällt mir irgendwie. :-D

Re: write int in file

Verfasst: Mittwoch 4. Juli 2012, 13:21
von snafu
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: