J'essaie de lire des données à partir d'une pile TCP et d'utiliser les données pour contrôler des interfaces externes, etc. Les données sont dans U32_T, donc si j'écris par exemple "Test" à l'interface La valeur Hex correspond à 0x74657374. Je souhaite convertir ces données en caractères correspondants afin qu'il soit plus facile d'utiliser les données. Comment convertir des valeurs hexadécimales dans un U32_T à sa chaîne de caractère?
J'ai essayé d'imprimer les données directement via le spécificateur de format% C, mais il ne montre que le premier caractère de la chaîne. P>
/* indicate that the packet has been received */ tcp_recved(tpcb, p->len); // Put actual data in 32 bit unsigned integer. tempPtr = (u32_t*)p->payload; // Print length of the actual data. xil_printf("Received package. Length = %d \r\n", p->len); // Reverse the data so it corresponds to the data sent. u32_t reversedTemp = byte_reverse_32(*tempPtr); // Prints hex value of data xil_printf("Data: %08x \r\n",reversedTemp); if (reversedTemp == 0x6C656431) { /* Read "led1" */ xil_printf("Data Read: led1"); } else if (reversedTemp == 0x74657374) { /* Read "test */ xil_printf("Data Read: test"); }
3 Réponses :
La solution la plus facile consiste à obtenir l'adresse de la variable, puis à lancer cela vers un char * code>.
if (memcmp("test", tempPtr), 4) {
// The input was "test"
}
Il y a un problème si les données pointées par TEMPPTR code> n'est pas NULL-TARNINÉE I>.
MemCMP code> pourrait être utilisé à la place.
Oups, c'est pourquoi j'ai utilisé STRNCMP mais j'ai oublié le dernier argument. Bon point sur MEMCMP cependant.
Vous avez un bug ici: Il n'y a pas besoin évident d'échanger les octets pour compenser l'endianess puisque vous avez l'intention de les convertir en une chaîne de toute façon (?). Si tel est le cas, vous pouvez le faire à la place (en supposant que le réseau Big Endian, CPU Little Endian): P> tempPtr = (u32_t *) p-> charge utile; code> ...
byte_réverse_32 (* tempptr) code>. C'est une violation aloritable stricte et très probablement également un accès mal aligné. Ne faites pas cela.
tcp_recved(tpcb, p->len);
char str[4+1] =
{
[0] = p->payload[3];
[1] = p->payload[2];
[2] = p->payload[1];
[3] = p->payload[0];
[4] = '\0'
};
donné: alors: p> Le renversement d'octets peut être inutile, vous pouvez simplement inverser le déballage pour obtenir la chaîne En une étape lorsque le premier caractère est dans la LSB: p> pour les cas spécifiques de: p> alors juste: p> Tout ce qui dit dans ce cas, votre solution existante est plus efficace que la chaîne ou la mémoire de la mémoire. Mais encore une fois, l'inversion d'octet est inutile - simplement inverser l'ordre d'octet dans l'entier et éviter les "nombres magiques": p> la conversion de chaîne reste peut-être utile, c'est que vous voulez sortir les chaînes de débogage ou de présentation humaine. p> p>
Vous ne pouvez pas utiliser
== code> pour comparer des chaînes dans C de toute façon, vous devez utiliser
STRCMP code>
pour comparer NULL-TARNINÉE i> B> Strings d'octets.Pour l'efficacité, ce que vous avez maintenant est assez optimal. Ce que je recommande, c'est que vous arrêtez d'utiliser numéros magiques et remplacez-les par des constantes symboliques ( Fondamentalement, les macros préprocesseurs), mais gardent sinon la comparaison actuelle (vous n'avez même pas besoin de faire l'étape de retour de retour, pour économiser quelques cycles de processeur et que le code aurait toujours du sens). Oh, et vous n'avez pas vraiment besoin du pointeur, faites plutôt par ex.
u32_t temp = * (u32_t *) p-> charge utile code>.
Enfin, si vous souhaitez toujours comparer à l'aide de Strings ASCII, vous pouvez utiliser
Memcmp code>
et ne pas avoir à la peine de se soucier de la résiliation null.Je dois noter que cela signifie-t-il que 0x74657374 ne doit-il pas être égal aux caractères T, E, S et T, respectivement? Et ne pas être une adresse sur un tableau de charcuterie.
Le fait que ce n'est pas une adresse à un tableau de charcuterie n'a pas d'importance car c n'est pas très sûr de type. Vous pouvez lancer des valeurs entre types Willy-Nilly et le compilateur ne se plaingent pas du tout. Étant donné que vous pouvez créer une variable:
u32_t led1 = 0x6c656431; code>; obtient ensuite son adresse et jeté à un "pointeur à un tableau de caractères":
(char *) LED1 code>; Et il serait techniquement approximativement équivalent à "LED1".
Oui avec la déclaration de l'adresse de LED1 en tant que char * je suis d'accord!
@SomeProgrammerDude aliasing strict !?
Il n'y a pas de "valeur hexagone", c'est juste un entier i>. L'hexagone est juste une représentation de l'entier.