19 Stimmen

C++: Umwandlung von 2 Bytes in einem Array in eine vorzeichenlose Kurzbezeichnung

Ich habe an einer C++-Legacy-Anwendung gearbeitet und befinde mich definitiv außerhalb meiner Komfortzone (was gut ist). Ich habe mich gefragt, ob jemand da draußen so freundlich wäre, mir ein paar Tipps zu geben (Wortspiel beabsichtigt).

Ich muss 2 Bytes in einem vorzeichenlosen Char-Array in ein vorzeichenloses Short umwandeln. Die Bytes sind fortlaufend.

Ein Beispiel dafür, was ich zu tun versuche:

Ich empfange eine Zeichenkette von einem Socket und lege sie in ein unsigned char-Array. Ich kann das erste Byte ignorieren und die nächsten 2 Bytes sollten dann in ein vorzeichenloses Zeichen umgewandelt werden. Dies wird auf Windows nur sein, so gibt es keine Big/Little Endian Probleme (die ich bewusst bin).

Hier ist, was ich jetzt habe (funktioniert natürlich nicht):

//packetBuffer is an unsigned char array containing the string "123456789" for testing
//I need to convert bytes 2 and 3 into the short, 2 being the most significant byte
//so I would expect to get 515 (2*256 + 3) instead all the code I have tried gives me
//either errors or 2 (only converting one byte
unsigned short myShort;
myShort = static_cast<unsigned_short>(packetBuffer[1])

0 Stimmen

Was muss dieser kerl jetzt von uns c++ programmierern denken. jeder hat eine andere "richtige" lösung :D

0 Stimmen

Nun, er könnte damit meinen, dass wir C++-Anwender ein schlaues Völkchen sind und die Regeln nach Belieben ändern. Mu ha haaa.

0 Stimmen

Enthält die Eingabe eine Zeichenkette mit Werten von '0'-'9' oder enthält sie Bytes mit Werten von 0-255? Die Dokumentation sagt String, aber es macht keinen Sinn, in diesem Fall mit 256 zu multiplizieren.

2voto

ilkayaktas Punkte 188

Vielleicht ist dies eine sehr späte Lösung, aber ich möchte sie Ihnen einfach mitteilen. Wenn Sie Primitive oder andere Typen konvertieren wollen, können Sie Union verwenden. Siehe unten:

union CharToStruct {
    char charArray[2];
    unsigned short value;
};

short toShort(char* value){
    CharToStruct cs;
    cs.charArray[0] = value[1]; // most significant bit of short is not first bit of char array
    cs.charArray[1] = value[0];
    return cs.value;
}

Wenn Sie ein Array mit den unten stehenden Hex-Werten erstellen und die Funktion toShort aufrufen, erhalten Sie einen kurzen Wert mit 3.

char array[2]; 
array[0] = 0x00;
array[1] = 0x03;
short i = toShort(array);
cout << i << endl; // or printf("%h", i);

1voto

arul Punkte 13880

Statische Besetzung hat eine andere Syntax, plus Sie müssen mit Zeigern arbeiten, was Sie tun möchten, ist:

unsigned short *myShort = static_cast<unsigned short*>(&packetBuffer[1]);

0 Stimmen

Das ist falsch! Es lässt sich nicht kompilieren. Obwohl ich es nicht empfehlen würde, ist zumindest reinterpret_cast ein besseres Angebot.

0 Stimmen

In der Tat kann static_cast nur die Umkehrung von [was eine implizite Standardkonvertierung kann, exklusive Konvertierung von einer abgeleiteten Klasse in eine ihrer virtuellen Basisklassen] unsigned short * p; unsigned char * c = p; funktioniert nicht

0 Stimmen

Achten Sie auf Ausrichtungsprobleme.

0voto

Martin York Punkte 245363

Hat niemand gesehen, dass die Eingabe eine Zeichenkette war!

/* If it is a string as explicitly stated in the question.
 */
int byte1 = packetBuffer[1] - '0'; // convert 1st byte from char to number.
int byte2 = packetBuffer[2] - '0';

unsigned short result = (byte1 * 256) + byte2;

/* Alternatively if is an array of bytes.
 */
int byte1 = packetBuffer[1];
int byte2 = packetBuffer[2];

unsigned short result = (byte1 * 256) + byte2;

Dadurch werden auch die Ausrichtungsprobleme vermieden, die bei den meisten anderen Lösungen auf bestimmten Plattformen auftreten können. Hinweis Ein Short ist mindestens zwei Bytes lang. Die meisten Systeme geben einen Speicherfehler aus, wenn Sie versuchen, einen Short-Zeiger zu de-referenzieren, der nicht auf 2 Byte ausgerichtet ist (oder was auch immer die sizeof(short) auf Ihrem System ist)!

0 Stimmen

Es handelt sich nicht um eine Zeichenkette - und die Bytes stehen nicht unbedingt für die Ziffern des Codesatzes.

1 Stimmen

Ich zitiere: 'packetBuffer ist ein unsigned char-Array, das die Zeichenkette "123456789" enthält'.

1 Stimmen

Ich zitiere: Ich empfange einen String von einem Socket und lege ihn in ein Array mit vorzeichenlosen Zeichen ab.

0voto

char packetBuffer[] = {1, 2, 3};
unsigned short myShort = * reinterpret_cast<unsigned short*>(&packetBuffer[1]);

Ich (musste) dies ständig tun. Big Endian ist ein offensichtliches Problem. Was wirklich zu Problemen führt, sind falsche Daten, wenn die Maschine nicht gerne falsch ausgerichtet liest! (und schreiben).

können Sie einen Test-Cast und eine Assert schreiben, um zu sehen, ob er richtig gelesen wird. Wenn es auf einer Big-Endian-Maschine oder, noch wichtiger, auf einer Maschine ausgeführt wird, die falsch ausgerichtete Lesevorgänge nicht mag, wird ein Assert-Fehler anstelle eines seltsamen, schwer zu verfolgenden "Bugs" auftreten ;)

0voto

Richard Punkte 683

Unter Windows können Sie verwenden:

unsigned short i = MAKEWORD(lowbyte,hibyte);

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