2010-08-24 5 views
28

pixel_data ist ein vector von char.Warum druckt printf beim hexadezimalen Ausdruck nicht nur ein Byte?

Wenn ich printf(" 0x%1x ", pixel_data[0]) mache, erwarte ich zu sehen 0xf5.

Aber ich bekomme 0xfffffff5, als ob ich eine 4-Byte-Ganzzahl anstelle von 1 Byte ausdrucken würde.

Warum ist das? Ich habe printf eine char zum Ausdrucken gegeben - es ist nur 1 Byte, also warum printf Drucken 4?

NB. die printf Implementierung ist in einer API von Drittanbietern verpackt, aber nur wundern, ob dies eine Funktion von Standard printf ist?

+2

Siehe auch: http://stackoverflow.com/questions/3512749/memcpy-adds-ff-ff-ff-to-the-beginning-of-a-byte –

Antwort

48

Du bist wahrscheinlich eine gutartige Form von undefinierten Verhalten bekommen, weil der %x Modifikator einen unsigned int Parameter und ein char erwartet wird in der Regel auf ein int gefördert werden, wenn sie ein geben varargs Funktion.

Sie sollten explizit die Zeichen auf eine unsigned int werfen vorhersehbare Ergebnisse zu erhalten:

printf(" 0x%1x ", (unsigned)pixel_data[0]); 

Beachten Sie, dass eine Feldbreite von einem nicht sehr nützlich ist. Es gibt lediglich die Mindestanzahl an Ziffern an, die angezeigt werden sollen, und in jedem Fall wird mindestens eine Ziffer benötigt.

Wenn char auf Ihrer Plattform dann wird diese Umwandlung konvertiert negative char Werte zu großen unsigned int Werten (z fffffff5) signiert ist. Wenn Sie Byte-Werte als vorzeichenlose Werte behandeln und bei der Konvertierung in unsigned int einfach null eingeben möchten, sollten Sie unsigned char für pixel_data verwenden oder über unsigned char umwandeln oder nach dem Hochstufen einen Maskierungsvorgang verwenden.

z.B.

printf(" 0x%x ", (unsigned)(unsigned char)pixel_data[0]); 

oder

printf(" 0x%x ", (unsigned)pixel_data[0] & 0xffU); 
+0

@charles. Danke für die Erklärung, warum die führenden 'f''s! Die API von Drittanbietern, die ich benutze, hat einen "unsigned char" -Typ - also habe ich meine Definition für "pixel_data" geändert, um diese stattdessen zu verwenden und die Ergebnisse zu erhalten, die ich brauche. – BeeBand

+1

@BeeBand: Seien Sie vorsichtig, wenn Sie nur auf "unsigned char" umstellen, reicht das nicht aus. Auf den meisten Plattformen wird "unsigned char" zu "int", nicht zu "unsigned int". –

+0

@Charles - wenn ich nicht auf "unsigned char" umstelle und nur die Besetzung mache, bekomme ich immer noch die führenden f's. Ich denke, ich muss beide auf "unsigned int" umstellen und eine Bitmaske verwenden, um sicherzustellen, dass sie auf allen Plattformen funktioniert. – BeeBand

3

Dann length Modifikator ist die minimale Länge.

+0

so 1 ist die Mindestlänge? Ich dachte, Längenmodifikator wäre in Bytes. – BeeBand

+3

Es ist die Länge in Zeichen. – leppie

+0

Sorry, ich verstehe einfach nicht, was du meinst. Warum bedeutet das, dass der Längenmodifikator die Mindestlänge ist? – BeeBand

2

Breitenspezifizierer in printf ist tatsächlich min-Breite. Sie können printf(" 0x%2x ", pixel_data[0] & 0xff) drucken, um Lowes-Byte zu drucken (Hinweis 2, um tatsächlich zwei Zeichen zu drucken, wenn pixel_data[0] zB 0xffffff02 ist).

7

Bessere Nutzung der Standard-Format-Flags

printf(" %#1x ", pixel_data[0]); 

dann Compiler setzt die Hex-Präfix für Sie.

+0

fantastisch! weil ich das nicht wusste, habe ich Debugger verwendet ... – Tebe

3

Verwenden %hhx

printf("%#04hhx ", foo); 
+0

Leider verwende ich eine API-Implementierung von Drittanbietern von 'printf', die den' hh'-Formatierer scheinbar nicht zulässt. Aber gut zu wissen - danke. – BeeBand