Umwandlung array in struct in c
Habe ich eine Struktur wie diese
struct packet
{
int seqnum;
char type[1];
float time1;
float pri;
float time2;
unsigned char data[512];
}
Ich bin empfangen von Paket in ein array
char buf[529];
Möchte ich die seqnum -, Daten-alles separat.Die folgenden festgelegten arbeiten.. Es gibt junk-Wert für mich.
struct packet *pkt;
pkt=(struct packet *)buf;
printf(" %d",pkt->seqnum)
- versuchen Sie zu Lesen, die gute Anzahl von bytes :
char buf[sizeof (struct packet)];
und mit :read (fd, buf, sizeof(struct packet));
- Sichergestellt, dass die Anzahl der gelesenen bytes entspricht der Größe der Struktur, aber es ändert nicht die eingehenden bytes und daher nichts tut, um sicherzustellen, dass Sie haben Polsterung oder endianness, die mit der Struktur. Wenn das eingehende Byte nicht drei bytes zwischen den
char type[1]
und diefloat time1
aber die Struktur macht, dannread
komplett gebrochen ist. - Zum Wohle der Schönheit, nicht immer geben die
Please help me with the code.
Satz wieder - Wollen Sie eine Lösung, die funktioniert in der standard-C-oder wollen Sie eine Lösung für eine konkrete Umsetzung in C? Die Umsetzung (inklusive der target-Plattform)?
- Eric Postpischil ich bin mit diesem mit gcc-compiler für ubuntu
Du musst angemeldet sein, um einen Kommentar abzugeben.
Nein, das wird wahrscheinlich nicht funktionieren und ist allgemein eine schlechte und kaputte Art und Weise, dies zu tun.
Müssen Sie compiler-spezifischen Erweiterungen, um sicherzustellen, gibt es keine unsichtbare Polsterung zwischen Ihre Struktur-die Mitglieder, für so etwas zu arbeiten. Mit gcc, zum Beispiel, tun Sie dies mit der
__attribute__()
syntax.Es ist also nicht eine tragbare Idee.
Es ist viel besser zu werden, ausdrücklich über Sie, und packen Sie jedes Feld. Dies gibt Ihnen auch eine chance haben, einen gut definierten endianness in Ihrem Netzwerk-Protokoll, das ist generell eine gute Idee für die Interoperabilität Willen.
Nein, das ist nicht allgemein gültigen code. Stellen Sie die Struktur, die erste und dann memcopy Sachen hinein:
Und so weiter.
Müssen Sie nehmen größter Sorgfalt, um den Typ Größen und endianness Recht.
Zuerst von all, Sie kann nicht im Voraus wissen, wo der compiler einfügen von padding-bytes in die Struktur der performance-Optimierung (cache-line-Ausrichtung, integer Ausrichtung, etc), da sich diese Plattform-abhängig. Außer, natürlich, wenn Sie erwägen den Bau der app nur auf Ihrer Plattform.
Sowieso, in Ihrem Fall scheint es, wie Sie immer sind Daten von irgendwo (Netzwerk ?) und es ist sehr wahrscheinlich, dass die Daten komprimiert wurden (keine padding-bytes zwischen den Feldern).
Wenn Sie wirklich wollen, zu festgelegten array einer struct-Zeiger ist, können Sie immer noch sagen, dass der compiler entfernen Sie die padding-bytes könnte es hinzufügen. Beachten Sie, dass diese abhängig von der compiler, den Sie verwenden, und ist kein standard-C-Implementierung. Mit gcc, könnten Sie diese Anweisung hinzufügen, die am Ende Ihrer Struktur-definition :
Beachten Sie, dass es Auswirkungen auf die Leistung für das Mitglied zugreifen, kopieren usw ...
Es sei denn, Sie haben einen sehr guten Grund, dies zu tun, verwenden Sie nicht immer die
__attribute__((packed))
Sache !Die andere Lösung, die ist viel mehr ratsam ist, um die Analyse auf Ihrer eigenen. Sie, nur weisen Sie eine geeignete Struktur und füllen Sie die Felder durch die Suche nach guten Informationen aus Ihrem Puffer. Eine Sequenz von
memcpy
Anleitung ist wahrscheinlich auf den trick zu tun hier (siehe Kerrek Antwort)__attribute__((packed))
ist nicht standard C, aber immer noch gültig sein, wenn der gleiche compiler verwendet wird, auf mehreren Plattformen. Übrigens, der OP ist der Kontext scheint zu implizieren, einige auf das Netzwerk bezogene code und so, Pakete sind gepackt, daher der Vorschlag.__attribute__
Sache schränkt zwar die Portabilität ein code-snippet in dem Sinne, dass manche Compiler nicht integrieren, werden die gewünschten Attribute, aber wenn der gleiche compiler verwendet wird, alle zusammen auf mehreren Plattformen, gibt es noch Portabilität in Plattformen ? (Ich bitte dies zu deutlich meine Meinung 🙂 )__attribute__((packed))
löst das padding-Problem aber nicht endianness Probleme oder andere Fragen, wie die Werte kodiert sind/vertreten (z.B., ob diefloat
Typ verwendet IEEE 754 oder wie groß dieint
Typ ist). Es gibt zwei Möglichkeiten, um dieses problem zu lösen: Schreiben Sie in der standard-C -, lese jedes byte einzeln und Umwandlung in einheimische Arten mithilfe von arithmetischen et cetera, oder schreiben Sie für eine bestimmte Implementierung und den Gegner mit den bytes in derstruct
vollständig definiert und implementierungsabhängig.