web-dev-qa-db-fra.com

Conversion d'un int en une valeur hexadécimale de 2 octets en C

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?

18
MBU

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

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;

4
slashmais
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().

3

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];
2
mikerobi

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.

2
MBU

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.

1
MAK
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);
....
1
cooxee

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
}
0
10SecTom

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);
0
Joe Valenzuela

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. 

0
Md. Yusuf

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.

0
manikanta

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

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;
}
0
jbremnant
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.

0
yasouser