2010-11-03 25 views
18

Necesito convertir un int a un valor hexadecimal de 2 bytes para almacenar en una matriz char, en C. ¿Cómo puedo hacer esto?Conversión de un int a un valor hexadecimal de 2 bytes en C

+0

el tipo de datos int es de 32 bits, mientras que el valor hexadecimal de 2 bytes es de 8 bits. Si su int es> 255, no cabe en su valor hexadecimal (se desbordará). ¿Te refieres a char firmado/sin firmar en lugar de int? – invert

+1

@wez: int no es necesariamente de 32 bits. Pero su pregunta es buena, él necesita vigilar el desbordamiento. – Vicky

+0

Esta pregunta parece una tarea ... ¿Es esto cierto? De ser así, agregue la etiqueta "tarea". –

Respuesta

30

Si está permitido el uso de funciones de biblioteca:

int x = SOME_INTEGER; 
char res[5]; /* two bytes of hex = 4 characters, plus NULL terminator */ 

if (x <= 0xFFFF) 
{ 
    sprintf(&res[0], "%04x", x); 
} 

Su número entero puede contener más de cuatro dígitos hexadecimales por valor de los datos, por lo tanto, el cheque primero.

Si usted no está permitido el uso de funciones de biblioteca, dividirlo abajo en nybbles manualmente:

#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

Al ver las respuestas de otras personas, parece que están interpretando "dos valores hexadecimales de bytes", que significa dos nybbles, cada uno representado por un carácter hexadecimal de un byte. Lo tomé como dos bytes de datos, cada uno representado por dos caracteres hexadecimales. ¡Tienes que aclarar a qué te refieres! – Vicky

+0

Gracias por la respuesta @Vicky. Lo usé para construir la función en la respuesta a continuación. – 10SecTom

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

es probable que desee para comprobar sprintf() documentación. Tenga cuidado de que este código no sea muy seguro. Si x es mayor que 0xFFFF, la cadena final tendrá más de 4 caracteres y no encajará. Para hacerlo más seguro, mira snprintf().

+0

si int es 11. Necesito que los 2 bytes resultantes sean 0 B, que es 11 en hexadecimal. – MBU

+0

Incorrecto, esos dos caracteres son medios bytes, también llamados nibbles. Un byte (8 bits, 0-255) se compone de 2 caracteres hexadecimales. Por lo tanto, 2 bytes están hechos de 4 caracteres hexadecimales. Cada chatarra (o mordisco) hexagonal tiene 4 bits (0-15, o 0-F). –

0

Tal vez intentar algo como esto:

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

Este código asume que las letras A a F ocupan puntos de código consecutivos. Esto no está garantizado por el lenguaje C. –

+0

¿Puedes pensar en alguna implementación o codificación que no tenga las letras consecutivamente? –

+3

Código de Baudot, "código-UPP" de la URSS (Код-УПП). – Vovanium

4

Suponiendo int a ser de 32 bits;

forma más fácil: sólo tiene que utilizar sprintf()

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

Ahora use hexval [0] a través de hexval [3]; si desea utilizarlo como una cadena terminada en cero luego añadir hexval[4]=0;

+1

Obtendrá resultados impredecibles (incluso bloqueo) cuando 0xFF Vovanium

+0

No. Dado que sprintf forma intval en una cadena. Así que 0xFFFF (que por cierto no es el valor máximo para un entero de 32 bits) sería cuatro F y no encajarían en hexval [3], ya que también debe considerar el 0 final. No tendrá que agregue hexval [2] = 0 por cierto. –

+0

bien, solo pagando a medias - tienes razón - corrigió – slashmais

1

En lugar de sprintf, recomendaría el uso de snprintf lugar.

#include <stdio.h> 

int main() 
{ 
    char output[5]; 
    snprintf(output,5,"%04x",255); 

    printf("%s\n",output); 
    return 0; 
} 

Es mucho más seguro, y está disponible en casi todos los compiladores.

0

La mayoría de estas respuestas son geniales, solo hay una cosa que agregaría: puede usar sizeof para reservar con seguridad la cantidad correcta de bytes. Cada byte puede tomar hasta dos dígitos hexadecimales (255 -> ff), por lo que son dos caracteres por byte. En este ejemplo, agrego dos caracteres para el prefijo '0x' y un carácter para el NUL posterior.

int bar; 
// ... 
char foo[sizeof(bar) * 2 + 3]; 
sprintf(foo, "0x%x", bar); 
0
unsigned int hex16 = ((unsigned int) input_int) & 0xFFFF; 

input_int es el número que desea convertir. hex16 tendrá los 2 bytes menos significativos de input_int. Si desea imprimirlo en la consola, use %x como el especificador de formato en lugar de %d y se imprimirá en formato hexadecimal.

2

Normalmente, recomendaría utilizar las soluciones basadas en sprintf recomendadas por otros. Pero cuando escribí una herramienta que tenía que convertir miles de millones de elementos en hexadecimal, sprintf era demasiado lento. Para esa aplicación usé una matriz de 256 elementos, que mapea bytes a cadenas.

Esta es una solución incompleta para convertir 1 byte, no olvide agregar la verificación de límites, y asegúrese de que la matriz sea estática o global, volver a crearla para cada control mataría el rendimiento.

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

Aquí hay una forma cruda de hacerlo.Si no podemos confiar en que la codificación de los valores de ascii sea consecutiva, simplemente creamos un mapeo de valores hexadecimales en char. Probablemente se pueda optimizar, arreglar y hacer más bonito. También asume que solo miramos capturar los últimos 32 bits == 4 caracteres hexadecimales.

#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 por carácter hexadecimal = 8 caracteres. No 4. –

2

Descubrí una manera rápida de probar y funciona.

int value = 11; 

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

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

resultado es:

000B 

que es 11 en hexadecimal.

0

Esta función funciona como un encanto.

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 lo siguiente:

typedef unsigned char BYTE; 
typedef unsigned short WORD; 

Ejemplo de uso:

que queremos lograr esto:

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

¿Le importa explicar su respuesta para que la gente pueda aprender de ella? – Machavity

0

puede utilizar este es simple y fácil de convertir

typedef union { 
    struct hex{ 
      unsigned char a; 
      unsigned char b; 

    }hex_da; 
    short int dec_val; 
}hex2dec; 

hex2dec value; 
value.dec_val=10; 

valor hexadecimal Ahora se almacena en la estructura hex_da acceder a ella para su uso posterior.

0

Usando la respuesta de Vicky anterior

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

Para dinámico longitud fija de hexagonal

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

Pero negativo que tiene que manejar por sí mismo.

Cuestiones relacionadas