2010-11-03 6 views
18

Je dois convertir un entier en une valeur hexadécimale de 2 octets pour le stocker dans un tableau de caractères, en C. Comment puis-je faire cela?Conversion d'un int en une valeur hexadécimale de 2 octets en C

+0

le type de données int est de 32 bits, tandis que la valeur hexadécimale de 2 octets est de 8 bits. Si votre int est> 255, il ne rentre pas dans votre valeur hexadécimale (il débordera). Voulez-vous dire char signé/non signé au lieu de int? – invert

+1

@wez: int n'est pas nécessairement 32 bits. Mais votre question est bonne, il faut faire attention au trop-plein. – Vicky

+0

Cette question ressemble à un devoir ... Est-ce vrai? Si oui, ajoutez la balise "devoirs". –

Répondre

30

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 entier peut contenir plus de quatre chiffres hexadécimaux d'une valeur de données, d'où la vérification d'abord.

Si vous n'êtes pas autorisé à utiliser des fonctions de bibliothèque, diviser le décomposer en quartets manuellement:

#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'; 
} 
+0

En voyant les réponses des autres, il semble qu'ils interprètent une "valeur hexadécimale à deux octets" signifiant deux bogues, chacun étant représenté par un octet hexadécimal. Je l'ai pris pour signifier deux octets de données, chacun représenté par deux caractères hexadécimaux. Vous devez préciser ce que vous voulez dire! – Vicky

+0

Merci pour la réponse @Vicky. Utilisé pour construire la fonction dans la réponse ci-dessous. – 10SecTom

3
char s[5]; // 4 chars + '\0' 
int x = 4660; 
sprintf(s, "%04X", x); 

Vous voudrez probablement vérifier 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 aura plus de 4 caractères et ne rentrera pas. Afin de le rendre plus sûr, regardez snprintf().

+0

si int est 11. J'ai besoin des 2 octets résultants pour être 0 B qui est 11 en hexadécimal. – MBU

+0

Incorrect, ces deux caractères sont des demi-octets, appelés aussi grignotements. Un octet (8 bits, 0-255) est composé de 2 caractères hexadécimaux. Ainsi, 2 octets sont constitués de 4 caractères hexadécimaux. Chaque caractère hexadécimal (ou grignotage) a 4 bits (0-15, ou 0-F). –

0

peut-être essayer quelque chose comme ceci:

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

Ce code suppose que les lettres A à F occupent des points de code consécutifs. Ce n'est pas garanti par le langage C. –

+0

Pouvez-vous penser à une implémentation ou un encodage qui n'a pas les lettres consécutivement? –

+3

Code Baudot, "code-UPP" de l'URSS (Код-УПП). – Vovanium

4

En supposant int être 32 bits;

façon la plus simple: il suffit d'utiliser sprintf()

int intval = /*your value*/ 
char hexval[5]; 
sprintf(hexval,"%0x",intval); 

utiliser maintenant hexval [0] à travers hexval [3]; si vous voulez l'utiliser comme une chaîne à zéro terminal puis ajoutez hexval[4]=0;

+1

Vous obtiendrez des résultats imprévisibles (même accident) lorsque 0xFF Vovanium

+0

Non. Depuis sprintf met en forme intval dans une chaîne. Donc 0xFFFF (qui n'est pas la valeur maximale pour un entier de 32 bits) serait de quatre F et ceux-ci ne rentreraient pas dans hexval [3], puisque vous devez aussi considérer le 0 de fin. Vous n'aurez pas à ajoutez hexval [2] = 0 en passant. –

+0

OK, ne payez qu'une demi-tête - vous avez raison - le corrige – slashmais

1

Plutôt que sprintf, je vous recommande d'utiliser snprintf à la place.

#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 à peu près tous les compilateurs.

0

La plupart de ces réponses sont excellentes, il y a une chose que j'ajouterais: vous pouvez utiliser sizeof pour réserver en toute sécurité le bon nombre d'octets. Chaque octet peut prendre jusqu'à deux chiffres hexadécimaux (255 -> ff), c'est 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
unsigned int hex16 = ((unsigned int) input_int) & 0xFFFF; 

input_int est le numéro que vous voulez convertir. hex16 aura le moins significatif 2 octets de input_int. Si vous voulez l'imprimer sur la console, utilisez %x comme spécificateur de format au lieu de %d et il sera imprimé au format hexadécimal.

2

Normalement, je recommande d'utiliser les solutions basées sur sprintf recommandées par d'autres. Mais quand j'ai écrit un outil qui devait convertir des milliards d'objets en hex, sprintf était trop lent. Pour cette application, j'ai utilisé un tableau de 256 éléments, qui mappe les octets aux chaînes.

Il s'agit d'une solution incomplète pour convertir 1 octet, n'oubliez pas d'ajouter la vérification des limites, et assurez-vous que le tableau est statique ou global, recréer pour chaque contrôle tuerait les performances.

static const char hexvals[][3]= {"00", "01", "02", ... "FD", "FE", "FF"}; 
const char *byteStr = hexvals[number]; 
0

Voici une manière brute de le faire.Si nous ne pouvons pas croire que le codage des valeurs ascii est consécutif, nous créons simplement un mappage des valeurs hexadécimales dans char. Probablement peut être optimisé, rangé, et rendu plus joli. Suppose également que nous ne regardons que la capture des 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

32 bits/4 bits-par-hex-caractère = 8 caractères. Non 4. –

2

J'ai trouvé un moyen rapide que j'ai testé et cela fonctionne.

int value = 11; 

array[0] = value >> 8; 
array[1] = value & 0xff; 

printf("%x%x", array[0], array[1]); 
résultat

est:

000B 

qui est 11 en hexadécimal.

0

Cette fonction fonctionne comme un charme.

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

asumming les éléments suivants:

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); 
1
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); 
.... 
+2

Vous voulez expliquer votre réponse afin que les gens puissent en tirer des leçons? – Machavity

0

vous pouvez utiliser cela, 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; 

valeur maintenant hex est stockée dans l'accès aux structures de hex_da pour une utilisation ultérieure.

0

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

Pour longueur fixe dynamique hexagonale

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 gérer vous-même.

Questions connexes