0
votes

Comment convertir cette valeur hexagonale dans une U32_T à sa valeur de caractère / ASCII correspondante?

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");
}


8 commentaires

Vous ne pouvez pas utiliser == pour comparer des chaînes dans C de toute façon, vous devez utiliser STRCMP pour comparer NULL-TARNINÉE 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 .


Enfin, si vous souhaitez toujours comparer à l'aide de Strings ASCII, vous pouvez utiliser Memcmp 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; ; obtient ensuite son adresse et jeté à un "pointeur à un tableau de caractères": (char *) LED1 ; 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 . L'hexagone est juste une représentation de l'entier.


3 Réponses :


0
votes

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"
}


2 commentaires

Il y a un problème si les données pointées par TEMPPTR n'est pas NULL-TARNINÉE . MemCMP 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.



0
votes

Vous avez un bug ici: 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.

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>

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'
};


0 commentaires

0
votes

donné: xxx

alors: xxx

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: xxx

pour les cas spécifiques de:

  • une cible de Big-Endian et le premier personnage de la MSB, ou
  • une cible à petite endiane et le premier personnage de la LSB,

    alors juste: xxx

    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": xxx

    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.


0 commentaires