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

1voto

Kevin Loney Punkte 7273

Char ist ein vorzeichenbehafteter Typ, so dass das, was Sie sehen, ist die Zwei-Kompliment-Darstellung, Casting zu (unsigned char*) wird das beheben (Rowland gerade geschlagen mich).

Nebenbei bemerkt, sollten Sie vielleicht Folgendes ändern

for (i=0; i<4; i++) {
//...
}

zu

for (i=0; i<sizeof(x); i++) {
//...
}

1voto

John Smith Punkte 11

Die Vorzeichenbehaftetheit von char array ist nicht die Wurzel des Problems! (Es ist -a- ein Problem, aber nicht das einzige Problem.)

Ausrichten! Das ist das Schlüsselwort hier. Aus diesem Grund sollten Sie NIEMALS versuchen, Strukturen wie Rohspeicher zu behandeln. Kompilierer (und verschiedene Optimierungsflags), Betriebssysteme und Mondphasen machen alle seltsame und aufregende Dinge mit der tatsächlichen Position von "benachbarten" Feldern in einer Struktur im Speicher. Wenn Sie z.B. eine Struktur mit einem char gefolgt von einem int haben, besteht die gesamte Struktur aus ACHT Bytes im Speicher - das char, 3 leere, nutzlose Bytes und dann 4 Bytes für den int. Die Maschine mag solche Dinge, damit Strukturen sauber auf Speicherseiten passen und dergleichen mehr.

Besuchen Sie einen Einführungskurs in die Maschinenarchitektur an Ihrer örtlichen Hochschule. In der Zwischenzeit sollten Sie richtig serialisieren. Behandeln Sie Structs niemals wie Char-Arrays.

1voto

InfinateOne Punkte 71

Wenn Sie die Nachricht senden wollen, verwenden Sie einfach:

(char*)&CustomPacket

zu konvertieren. Funktioniert bei mir.

0voto

Otávio Décio Punkte 72052

Möglicherweise möchten Sie in ein Array mit vorzeichenlosen Zeichen konvertieren.

-1voto

Norman Ramsey Punkte 193087

Es sei denn, Sie haben très überzeugende Messungen, die zeigen, dass jedes Oktett wertvoll ist, Tun Sie das nicht . Verwenden Sie ein lesbares ASCII-Protokoll wie SMTP , NNTP oder eines der vielen anderen guten Internet-Protokolle, die von der IETF kodifiziert wurden.

Wenn Sie wirklich ein binäres Format benötigen, ist es trotzdem nicht sicher, die Bytes einfach in eine Struktur zu packen, da die Byte-Reihenfolge, die Basisgrößen oder die Ausrichtungsbeschränkungen von Host zu Host unterschiedlich sein können. Sie müssen Ihr Drahtprotokoll so gestalten, dass Sie wohldefinierte Größen und eine wohldefinierte Bytereihenfolge verwenden. Verwenden Sie für Ihre Implementierung entweder Makros wie ntohl(3) oder verwenden Sie Shifting und Masking, um Bytes in Ihren Stream einzufügen. Was auch immer Sie tun, stellen Sie sicher, dass Ihr Code auf Big-Endian- und Little-Endian-Hosts die gleichen Ergebnisse liefert.

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