9 Stimmen

Wie konvertiert man struct in char array in C

Ich versuche, eine Struktur in ein Char-Array zu konvertieren, um über das Netzwerk zu senden. Allerdings bekomme ich einige seltsame Ausgabe von der Char-Array, wenn ich tun.

#include <stdio.h>

struct x
{
   int x;
} __attribute__((packed));

int main()
{
   struct x a;
   a.x=127;
   char *b = (char *)&a;
   int i;
   for (i=0; i<4; i++)
      printf("%02x ", b[i]);
   printf("\n");
   for (i=0; i<4; i++)
      printf("%d ", b[i]);
   printf("\n");
   return 0;
}

Hier ist die Ausgabe für verschiedene Werte von a.x (auf einem X86 mit gcc):
127:
7f 00 00 00
127 0 0 0

128:
ffffff80 00 00 00
-128 0 0 0

255:
ffffffff 00 00 00
-1 0 0 0

256:
00 01 00 00
0 1 0 0

Ich verstehe die Werte für 127 und 256, aber warum ändern sich die Zahlen beim Übergang zu 128? Warum sollte es nicht einfach sein: 80 00 00 00 128 0 0 0

Habe ich bei der Konvertierung etwas vergessen, oder habe ich etwas über die Darstellung ganzer Zahlen vergessen?

*Anmerkung: Dies ist nur ein kleines Testprogramm. In einem echten Programm habe ich mehr in der Struktur, bessere Variablennamen, und ich konvertiere in Little-Endian.
*Bearbeitung: Formatierung

11voto

Was Sie sehen, ist die vorzeichenerhaltende Umwandlung von char in int. Das Verhalten resultiert aus der Tatsache, dass auf Ihrem System char vorzeichenbehaftet ist ( Note : char ist nicht auf allen Systemen signiert). Das führt zu negativen Werten, wenn ein Bitmuster einen negativen Wert für ein Zeichen ergibt. Wenn Sie ein solches Zeichen in einen int-Wert umwandeln, bleibt das Vorzeichen erhalten und der int-Wert ist ebenfalls negativ. Beachten Sie, dass selbst wenn Sie kein (int) explizit angeben, wird der Compiler das Zeichen bei der Übergabe an printf automatisch in einen int umwandeln. Die Lösung ist die Konvertierung des Wertes in unsigned char Erstens:

for (i=0; i<4; i++)
   printf("%02x ", (unsigned char)b[i]);

Alternativ können Sie auch unsigned char* von Anfang an:

unsigned char *b = (unsigned char *)&a;

Und dann braucht man beim Drucken mit printf keinen Cast mehr.

8voto

Rowland Shaw Punkte 37027

Char ist ein Typ mit Vorzeichen; im Zweierkomplement ist 0x80 also -128 für eine 8-Bit-Ganzzahl (d. h. ein Byte)

8voto

Rob Kennedy Punkte 158781

Le site x Formatangabe allein besagt, dass das Argument ein int und da die Zahl negativ ist, printf benötigt acht Zeichen, um alle vier Nicht-Null-Bytes der int -großen Wert. Die Website 0 wird die Ausgabe mit Nullen aufgefüllt, und der Modifikator 2 Modifikator besagt, dass die Minimum Ausgabe sollte zwei Zeichen lang sein. Soweit ich das beurteilen kann, printf bietet keine Möglichkeit zur Angabe einer maximal Breite, außer bei Zeichenketten.

Nun denn, Sie übergeben nur eine char so kahl x sagt der Funktion, dass sie die vollständige int das stattdessen übergeben wurde - aufgrund der Standardargumentförderung für " ... Parameter". Versuchen Sie die hh Modifikator, um der Funktion mitzuteilen, dass sie das Argument nur als char stattdessen:

printf("%02hhx", b[i]);

5voto

Die Behandlung Ihrer Struktur als char-Array ist ein undefiniertes Verhalten. Um es über das Netzwerk zu senden, verwenden Sie stattdessen eine korrekte Serialisierung. Es ist ein Schmerz in C++ und noch mehr in C, aber es ist der einzige Weg, Ihre App wird unabhängig von den Maschinen lesen und schreiben zu arbeiten.

http://en.wikipedia.org/wiki/Serialization#C

2voto

Brian Clapper Punkte 24335

Wenn Sie Ihre Struktur in Zeichen oder Bytes umwandeln, wird das zu Problemen führen, wenn Sie versuchen, sie netzneutral zu gestalten. Warum sollte man dieses Problem nicht jetzt angehen? Es gibt eine Reihe verschiedener Techniken, die Sie anwenden können und die wahrscheinlich alle "portabler" sind als das, was Sie gerade versuchen. Zum Beispiel:

  • Das maschinenunabhängige Senden numerischer Daten über das Netz wird in der POSIX/Unix-Welt seit langem mit den Funktionen htonl , htons , ntohl y ntohs . Siehe zum Beispiel die byteorder(3) Handbuchseite auf einem FreeBSD- oder Linux-System.
  • Konvertierung von Daten in und aus einer völlig neutralen Darstellung wie JSON ist ebenfalls vollkommen akzeptabel. Die Zeit, die Ihre Programme für die Konvertierung der Daten zwischen JSON und nativen Formen aufwenden, dürfte im Vergleich zu den Latenzen bei der Netzwerkübertragung verblassen.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X