Je dois convertir un int en une valeur hexadécimale de 2 octets à stocker dans un tableau de caractères, en C. Comment puis-je faire cela?
Si vous êtes autorisé à utiliser les fonctions de la bibliothèque:
int x = SOME_INTEGER;
char res[5]; /* two bytes of hex = 4 characters, plus NULL terminator */
if (x <= 0xFFFF)
{
sprintf(&res[0], "%04x", x);
}
Votre nombre entier peut contenir plus de quatre chiffres hexadécimaux de données, d’où la vérification en premier lieu.
Si vous n'êtes pas autorisé à utiliser les fonctions de la bibliothèque, divisez-le manuellement en nybbles:
#define TO_HEX(i) (i <= 9 ? '0' + i : 'A' - 10 + i)
int x = SOME_INTEGER;
char res[5];
if (x <= 0xFFFF)
{
res[0] = TO_HEX(((x & 0xF000) >> 12));
res[1] = TO_HEX(((x & 0x0F00) >> 8));
res[2] = TO_HEX(((x & 0x00F0) >> 4));
res[3] = TO_HEX((x & 0x000F));
res[4] = '\0';
}
En supposant que int soit 32 bits;
manière la plus simple: utilisez simplement sprintf ()
int intval = /*your value*/
char hexval[5];
sprintf(hexval,"%0x",intval);
Maintenant, utilisez hexval [0] à hexval [3]; si vous voulez l'utiliser comme chaîne terminée par un zéro, ajoutez hexval[4]=0;
char s[5]; // 4 chars + '\0'
int x = 4660;
sprintf(s, "%04X", x);
Vous voudrez probablement consulter la documentation sprintf()
. Veillez à ce que ce code ne soit pas très sûr. Si x
est supérieur à 0xFFFF
, la chaîne finale comportera plus de 4 caractères et ne tiendra pas. Afin de le rendre plus sûr, regardez snprintf()
.
Normalement, je recommanderais l’utilisation des solutions sprintf
recommandées par d’autres. Mais lorsque j'ai écrit un outil qui devait convertir des milliards d'éléments en hexadécimal, sprintf était trop lent. Pour cette application, j'ai utilisé un tableau de 256 éléments, qui mappe des octets en chaînes.
Il s'agit d'une solution incomplète pour la conversion d'un octet. N'oubliez pas d'ajouter une vérification des limites et assurez-vous que le tableau est statique ou global. Le recréer à chaque vérification pourrait réduire les performances.
static const char hexvals[][3]= {"00", "01", "02", ... "FD", "FE", "FF"};
const char *byteStr = hexvals[number];
Compris un moyen rapide que j'ai testé et que ça marche.
int value = 11;
array[0] = value >> 8;
array[1] = value & 0xff;
printf("%x%x", array[0], array[1]);
le résultat est:
000B
qui est 11 dans l'hex.
Plutôt que sprintf
, je recommanderais plutôt d'utiliser snprintf
.
#include <stdio.h>
int main()
{
char output[5];
snprintf(output,5,"%04x",255);
printf("%s\n",output);
return 0;
}
C'est beaucoup plus sûr et est disponible dans presque tous les compilateurs.
void intToHex(int intnumber, char *txt)
{
unsigned char _s4='0';
char i=4;
//intnumber=0xffff;
do {
i--;
_s4 = (unsigned char) ((intnumber >> i*4 ) & 0x000f);
if(_s4<10)
_s4=_s4+48;
else
_s4=_s4+55;
*txt++= _s4;
} while(i);
}
...
char text [5]={0,0,0,0,0};
...
intToHex(65534,text);
USART_Write_Text(text);
....
En utilisant la réponse de Vicky ci-dessus
typedef unsigned long ulong;
typedef unsigned char uchar;
#define TO_HEX(i) (i <= 9 ? '0' + i : 'A' - 10 + i)
#define max_strhex (sizeof(ulong)*2)
public uchar
*mStrhex(uchar *p, ulong w, ulong n)
{
ulong i = 0xF; // index
ulong mask = i << (((sizeof(ulong)*2)-1)*4); // max mask (32 bit ulong mask = 0xF0000000, 16 bit ulong mask = 0xF000)
ulong shift = (w*4); // set up shift to isolate the highest nibble
if(!w || w > max_strhex) // no bold params
return p; // do nothing for the rebel
mask = mask >> (max_strhex-w)*4; // setup mask to extract hex nibbles
for(i = 0; i < w; i++){ // loop and add w nibbles
shift = shift - 4; // hint: start mask for four bit hex is 0xF000, shift is 32, mask >> 32 is 0x0000, mask >> 28 is 0x000F.
*p++ = TO_HEX(((n & mask) >> shift)); // isolate digit and make hex
mask = mask >> 4; //
*p = '\0'; // be Nice to silly people
} //
return p; // point to null, allow concatenation
}
La plupart de ces réponses sont excellentes, il n’ya qu’une chose à ajouter: vous pouvez utiliser sizeof pour réserver en toute sécurité le nombre correct d’octets. Chaque octet peut prendre jusqu'à deux chiffres hexadécimaux (255 -> ff), donc deux caractères par octet. Dans cet exemple, j'ajoute deux caractères pour le préfixe '0x' et un caractère pour le NUL final.
int bar;
// ...
char foo[sizeof(bar) * 2 + 3];
sprintf(foo, "0x%x", bar);
Pour dynamique longueur fixe d'hex
string makeFixedLengthHex(const int i, const int length)
{
std::ostringstream ostr;
std::stringstream stream;
stream << std::hex << i;
ostr << std::setfill('0') << std::setw(length) << stream.str();
return ostr.str();
}
Mais négatif, vous devez le gérer vous-même.
vous pouvez l'utiliser, il est simple et facile à convertir
typedef union {
struct hex{
unsigned char a;
unsigned char b;
}hex_da;
short int dec_val;
}hex2dec;
hex2dec value;
value.dec_val=10;
Maintenant, la valeur hexadécimale est stockée dans la structure hexa_da. Accédez-y pour une utilisation ultérieure.
Peut-être essayer quelque chose comme ça:
void IntToHex(int value, char* buffer) {
int a = value&16;
int b = (value>>4)&16;
buffer[0] = (a<10)?'0'+a:'A'-(a-10);
buffer[1] = (b<10)?'0'+b:'A'-(b-10);
}
Cette fonction fonctionne à merveille.
void Word2WBYTE(BYTE WBYTE[2], Word Value) {
BYTE tmpByte[2];
// Converts a value from Word to Word byte ----
memcpy(tmpByte, (BYTE*) & Value, 2);
WBYTE[1] = tmpByte[0];
WBYTE[0] = tmpByte[1];
}
en remplissant ce qui suit:
typedef unsigned char BYTE;
typedef unsigned short Word;
Exemple d'utilisation:
nous voulons atteindre cet objectif:
integer = 92
byte array in hex:
a[0] = 0x00;
a[1] = 0x5c;
unsigned char _byteHex[2];
Word2WBYTE(_byteHex, 92);
Voici une façon grossière de le faire. Si nous ne pouvons pas faire confiance à l'encodage des valeurs ascii pour être consécutif, nous créons simplement un mappage des valeurs hexadécimales dans char. Peut probablement être optimisé, rangé et rendu plus joli. Suppose également que nous ne regardons que capturer les 32 derniers bits == 4 caractères hexadécimaux.
#include <stdlib.h>
#include <stdio.h>
#define BUFLEN 5
int main(int argc, char* argv[])
{
int n, i, cn;
char c, buf[5];
char hexmap[17] = {'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F','.'};
for(i=0;i<BUFLEN;i++)
buf[i]=0;
if(argc<2)
{
printf("usage: %s <int>\n", argv[0]);
return 1;
}
n = atoi(argv[1]);
i = 0;
printf("n: %d\n", n);
for(i=0; i<4; i++)
{
cn = (n>>4*i) & 0xF;
c = (cn>15) ? hexmap[16] : hexmap[cn];
printf("cn: %d, c: %c\n", cn, c);
buf[3-i] = (cn>15) ? hexmap[16] : hexmap[cn];
}
buf[4] = '\0'; // null terminate it
printf("buf: %s\n", buf);
return 0;
}
unsigned int hex16 = ((unsigned int) input_int) & 0xFFFF;
input_int
est le nombre que vous souhaitez convertir. hex16
aura les 2 octets les moins significatifs de input_int
. Si vous souhaitez l'imprimer sur la console, utilisez %x
comme spécificateur de format au lieu de %d
et il sera imprimé au format hexadécimal.