Wie drucke ich unsigned char als zweistelligen Hex-Wert in C?

Lesezeit: 5 Minuten

Benutzer-Avatar
Asad Waheed

Ich versuche, einen unsigned char-Wert als 2-stelligen Hex-Wert auszudrucken, bekomme aber immer das Ergebnis als 4-stelligen Hex-Wert, nicht sicher, was mit meinem Code falsch ist.

// unsigned char declaration
unsigned char status = 0x00;
// printing out the value 
printf("status = (0x%02X)\n\r", (status |= 0xC0));

Ich erwarte ein 2-stelliges Hex-Ergebnis als 0xC0aber ich bekomme immer 0xC0FF.

Auch als ich versuchte, dieselbe Variable (Status) als unsigned char mit dem zu drucken %bu Formatkennung habe ich die Ausgabe als erhalten 255.

Wie bekommt man nur die beiden Hex-Zeichen als Ausgabe?

  • Es gäbe mehr Möglichkeiten zu erklären, was vor sich ging, wenn die Ausgabe 0xFFC0 wäre (obwohl dies an Compiler-Bug-Territorium grenzen würde). Was passiert, wenn Sie die bewegen |= Zuordnung in eine separate Anweisung vor der printf()? Wenn sich das Ergebnis ändert, müssen Sie sich wahrscheinlich um einen Compiler-Fehler kümmern. Welche Version welchen Compilers verwenden Sie auf welcher Version welcher Plattform (o/s)?

    – Jonathan Leffler

    10. September 2012 um 2:58 Uhr

  • IDE-Version: µVision V4.02 Copyright (c) Keil Elektronik GmbH / Keil Software, Inc. 1995 – 2009 Tool-Versionsnummern: Toolchain: PK51 Prof. Developers Kit Version: 9.01 Toolchain-Pfad: C:\Software\Keil\C51\ BIN\ C Compiler: C51.Exe V9.01 Assembler: A51.Exe V8.02 Linker/Locator: BL51.Exe V6.22 Librarian: LIB51.Exe V4.24 Hex Converter: OH51.Exe V2.6 CPU DLL: S8051 .DLL V3.72 Dialog-DLL: DP51.DLL V2.59

    – Asad Waheed

    10. September 2012 um 3:00 Uhr


  • Wenn ich ein kleines Programm ausführe, das den von Ihnen gezeigten Code enthält, ist die Ausgabe status = (0xC0). Sind Sie sicher, dass der Code ist exakt Was steht in deinem Programm? Schreiben Sie ein kleines in sich geschlossenes Programm (mit #include <stdio.h> und eine vollständige Definition der main() Funktion) und zeigen Sie uns diese zusammen mit Ihrer Ausgabe. Beides kopieren und einfügen; geben Sie sie nicht erneut ein.

    – Keith Thompson

    10. September 2012 um 3:02 Uhr

  • Soweit ich weiß, generiert Keil C Code für den 8051 (eine kleine CPU für eingebettete Systeme), und ich glaube nicht, dass er vollständig dem C-Standard entspricht. Ihr Programm sollte richtig funktionieren. Ich habe ein „keil“-Tag hinzugefügt; Vielleicht wird das die Aufmerksamkeit von jemandem auf sich ziehen, der mehr über die Launen des von Ihnen verwendeten Compilers weiß.

    – Keith Thompson

    10. September 2012 um 3:04 Uhr


  • Übrigens Ihre printf() Formatzeichenfolge enthält \n\r. Das ist nicht die herkömmliche Reihenfolge für das CRLF-Zeilenende; normalerweise würdest du schreiben \r\n. Mit der Ausgabe der Zahl dürfte das aber nur sehr wenig zu tun haben.

    – Jonathan Leffler

    10. September 2012 um 3:07 Uhr

Soweit ich weiß, die Keil-C-Compiler entspricht nicht vollständig dem C-Standard. Wenn dies der Fall ist, entspricht es wahrscheinlich nicht ganz den Standard-Beförderungsregeln für Dinge wie das Bestehen char Werte zu variadischen Funktionen; Auf einer 8-Bit-CPU gibt es Leistungsvorteile, wenn 8-Bit-Werte nicht automatisch auf 16 Bit oder mehr erweitert werden.

Als Problemumgehung können Sie die höherwertigen Bits explizit abschneiden, bevor Sie das Argument an übergeben printf. Versuche dies:

#include <stdio.h>

int main(void) {
    unsigned char status = 0x00;
    status |= 0xC0;

    printf("status = 0x%02X\n", (unsigned int)(status & 0xFF));
    return 0;
}

Machen Sie ein bitweises “und” mit 0xFF löscht alle außer den unteren 8 Bits; Gießen zu unsigned int sollte nicht notwendig sein, aber es garantiert, dass das Argument tatsächlich von der Art ist, die von erwartet wird printf mit einer "%02X" Format.

Sie sollten auch in der Dokumentation Ihrer Implementierung nachsehen, ob es sich um nicht standardmäßiges Verhalten bei Typumstiegen und handelt printf.

  • Danke für diese Workaround-Lösung. Es funktioniert korrekt.

    – Asad Waheed

    10. September 2012 um 3:26 Uhr

  • Das & 0xFF sollte nicht notwendig sein, es sei denn, der Compiler ist weitaus kaputter, als char-Argumente nicht implizit in int umzuwandeln. Die Ausgabe von 0xC0FF deutet darauf hin, dass die Konvertierung tatsächlich nicht durchgeführt wird und die anderen 8 Bits aus dem Müll auf dem Stapel oder in einem Register übrig bleiben. Aber +1 für den guten Fang.

    – Jim Balter

    10. September 2012 um 3:41 Uhr


Sie senden ein Zeichen an eine Formatzeichenfolge, die ein Int erwartet. Die printf-Funktion greift ein weiteres Byte aus dem Stapel, um es aufzufüllen. Versuchen

 printf("%02X",(int)(status|0xC0));

  • Können Sie mir sagen, wie ich es als Hex drucken kann (was es als unsigned char erwartet)?

    – Asad Waheed

    10. September 2012 um 2:50 Uhr

  • Falsch. Seit printf ist eine variadische Funktion, Argumente vom Typ char oder unsigned char dazu befördert werden int (oder, auf einigen exotischen Systemen, unsigned int). Und "%02X" erwartet unsigned intnicht int.

    – Keith Thompson

    10. September 2012 um 2:50 Uhr


  • unsigned char wird befördert int Weil printf() ist eine variadische Funktion (angenommen <stdio.h> ist enthalten). Wenn der Header nicht enthalten ist, dann (a) sollte es sein und (b) Sie haben keinen Prototyp im Geltungsbereich, also die unsigned char wird noch befördert int.

    – Jonathan Leffler

    10. September 2012 um 2:53 Uhr


  • Und es stellte sich heraus, dass ich größtenteils aus Versehen recht hatte. 🙂 Der Fehler roch sicher nach einer Nichtübereinstimmung zwischen Anrufer und Angerufenem.

    – AShelly

    11. September 2012 um 20:36 Uhr


Benutzer-Avatar
Kemin Zhou

Wenn ich mir alle Antworten ansehe, denke ich, dass uns wahrscheinlich eine andere Möglichkeit fehlt, dies zu tun.

const unsigned char chararr[]="abceXYZ";
for (int i=0; i< 7; ++i) {
    printf("%#04X %d %c\n", chararr[i], chararr[i], chararr[i]);
}
0X61 97 a
0X62 98 b
0X63 99 c
0X65 101 e
0X58 88 X
0X59 89 Y
0X5A 90 Z

Wenn Sie %#04x kleines x verwenden, wird die Ausgabe ein 0x kleines x-Präfix sein. Das Nummernzeichen # weist die Funktion an, das 0x auszugeben. 04, um anzugeben, wie viele Ziffern ausgegeben werden sollen. Wenn die Eingabe ‘0x0a’ ist, wird dies gedruckt, ohne 04 wird ‘0xa’ gedruckt.

In meinem Computer, Dell Workstation, ist die Ausgabe wie von der Frage erwartet. Wenn nicht

unsigned char status = 0x00;
printf("status = (0x%02X)\n\r", (status |= 0xC0));
// output
//status = (0xC0)
// is exactly expected by the original question. 

An Beispielen besser verdeutlicht:

 37    printf("status = (%#02x)\n", (status |= 0xC0));
 38    printf("status = (%#04x)\n", (status |= 0xC0));
 39    printf("status = (%#04x)\n", 0x0f);
 40    printf("status = (%#02x)\n", 0x0f);
status = (0xc0)
status = (0xc0)
status = (0x0f)
status = (0xf)

  • Toller Code für alles auf einem Bildschirm, sauber und präzise. Diese Arbeit für mich.

    – Florida

    28. April 2020 um 4:13 Uhr

Cast es zu unsigned char:

printf("status = (0x%02X)\n\r", (unsigned char)(status |= 0xC0));

1180600cookie-checkWie drucke ich unsigned char als zweistelligen Hex-Wert in C?

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy