Formatspezifizierer für kurze Ganzzahl
-
22-10-2019 - |
Frage
Ich verwende die Formatspezifizierer in C nicht richtig ein paar Codezeilen:
int main()
{
char dest[]="stack";
unsigned short val = 500;
char c = 'a';
char* final = (char*) malloc(strlen(dest) + 6);
snprintf(final, strlen(dest)+6, "%c%c%hd%c%c%s", c, c, val, c, c, dest);
printf("%s\n", final);
return 0;
}
Was ich möchte, ist zu kopieren
Finale [0] = ein zufälliger char final [1] = ein zufälliger char final [2] und endgültig [3] = das kurze Array -Finale [4] = ein weiteres Zeichen ....
Mein Problem ist, dass ich die beiden Bytes des kurzen Int auf 2 Bytes des endgültigen Arrays kopieren möchte.
Danke.
Lösung
Ich bin verwirrt - das Problem ist, dass Sie sagen strlen(dest)+6
was die Länge der Länge der begrenzt final
Saite bis 10 Zeichen (plus ein Null -Terminator). Wenn du sagst strlen(dest)+8
Dann gibt es genug Platz für die vollständige Saite.
Aktualisieren
Auch wenn ein kurzer Wert nur 2 Bytes beträgt, wird jedes Zeichen ein Byte aufnimmt, wenn er als Zeichenfolge gedruckt wird. Das bedeutet also, dass es bis zu 5 Bytes Platz erfordern kann, um einen Kurzfilm in eine Zeichenfolge zu schreiben, wenn Sie eine Nummer über 10000 schreiben.
Wenn Sie nun den Kurzfilm in eine Zeichenfolge als Hexadezimalzahl schreiben, verwenden Sie die %x
Formatspezifizierer, es wird nicht mehr als 2 Bytes in Anspruch nehmen.
Andere Tipps
Sie müssen Platz für 13 Zeichen zuordnen - nicht 11. Vergessen Sie nicht die Beendigung von Null.
Wenn die Nummer (500) formatiert wurde, nimmt er drei Plätze ein, nicht eins. Also dein snsprintf
sollte die endgültige Länge als geben strlen(dest)+5+3
. Dann reparieren Sie auch Ihre malloc
Rufen Sie an, um sich anzupassen. Wenn Sie die berechnen möchten strlen
von der Nummer, tun Sie das mit einem Anruf wie diesem strlen(itoa(val))
. Ich kann den Null am Ende des Ziels auch nicht vergessen, aber ich denke, Strlen berücksichtigt dies, aber ich bin nicht sicher.
Einfache Antwort ist, dass Sie nur genug Platz für das Strlen (dest After + dest (5 Zeichen) = 13 Zeichen, wenn Sie 11 Zeichen zugewiesen haben.
Unsigned short
s kann bis zu 5 Zeichen nehmen, oder? (0 - 65535)
Scheint, als müssten Sie 5 Zeichen für Ihre zuweisen unsigned short
alle Werte abdecken.
Dies würde darauf hinweisen, dass dies verwendet wird:
char* final = (char*) malloc(strlen(dest) + 10);
Sie verlieren ein Byte, weil Sie der Meinung sind, dass die kurze Variable 2 Byte nimmt. Aber es dauert drei: eine für jedes Zifferncharakter ('5', '0', '0'). Außerdem brauchst du eine '\0'
Terminator (+1 Byte).
==> Sie brauchen strlen(dest) + 8
Verwenden Sie 8 statt 6 auf:
char* final = (char*) malloc(strlen(dest) + 6);
und
snprintf(final, strlen(dest)+6, "%c%c%hd%c%c%s", c, c, val, c, c, dest);
Es scheint, als ob das primäre Missverständnis darin besteht, dass ein "2-Byte" -Kurzel auf dem Bildschirm nicht als 2 1-Byte-Charaktere dargestellt werden kann.
Lassen Sie zuerst genug Platz:
char* final = (char*) malloc(strlen(dest) + 9);
Der gesamte Bereich der möglichen Werte für einen 1-Byte-Zeichen ist nicht druckbar. Wenn Sie dies auf dem Bildschirm anzeigen und lesbar sein möchten, müssen Sie die 2-Byte-Kurzfilme als 4 Hex-Bytes codieren, wie z. B.:
## as hex, 4 characters
snprintf(final, sizeof(final), "%c%c%4x%c%c%s", c, c, val, c, c, dest);
Wenn Sie dies in eine Datei schreiben, ist das in Ordnung, und Sie können Folgendes ausprobieren:
## print raw bytes, upper byte, then lower byte.
snprintf(final, sizeof(final), "%c%c%c%c%c%c%s", c, c, ((val<<8)&0xFF), ((val>>8)&0xFF), c, c, dest);
Aber das macht keinen Sinn für einen Menschen, der es betrachtet, und ist empfindlich gegenüber Endianz. Ich würde es dringend empfehlen.