Hexagonal a matriz de caracteres en C

Dada una cadena de valores hexadecimales, es decir, por ejemplo, “0011223344”, es decir 0x00, 0x11, etc.

¿Cómo agrego estos valores a una matriz char?

Equivalente a decir:

char array[4] = { 0x00, 0x11 ... }; 

No puede caber 5 bytes de datos en una matriz de 4 bytes; eso conduce a desbordamientos de búfer.

Si tiene los dígitos hexadecimales en una cadena, puede usar sscanf() y un ciclo:

 #include  #include  int main() { const char *src = "0011223344"; char buffer[5]; char *dst = buffer; char *end = buffer + sizeof(buffer); unsigned int u; while (dst < end && sscanf(src, "%2x", &u) == 1) { *dst++ = u; src += 2; } for (dst = buffer; dst < end; dst++) printf("%d: %c (%d, 0x%02x)\n", dst - buffer, (isprint(*dst) ? *dst : '.'), *dst, *dst); return(0); } 

Tenga en cuenta que imprimir la cadena que comienza con un byte cero requiere cuidado; la mayoría de las operaciones terminan en el primer byte nulo. Tenga en cuenta que este código no anuló la terminación del búfer; no está claro si la terminación nula es deseable, y no hay suficiente espacio en el búfer que declare para agregar un terminal nulo (pero que se soluciona fácilmente). Existe una posibilidad decente de que si el código se empaquetó como una subrutina, tendría que devolver la longitud de la cadena convertida (aunque también podría argumentarse que es la longitud de la cadena fuente dividida entre dos).

Haría algo como esto;

 // Convert from ascii hex representation to binary // Examples; // "00" -> 0 // "2a" -> 42 // "ff" -> 255 // Case insensitive, 2 characters of input required, no error checking int hex2bin( const char *s ) { int ret=0; int i; for( i=0; i<2; i++ ) { char c = *s++; int n=0; if( '0'<=c && c<='9' ) n = c-'0'; else if( 'a'<=c && c<='f' ) n = 10 + c-'a'; else if( 'A'<=c && c<='F' ) n = 10 + c-'A'; ret = n + ret*16; } return ret; } int main() { const char *in = "0011223344"; char out[5]; int i; // Hex to binary conversion loop. For example; // If in="0011223344" set out[] to {0x00,0x11,0x22,0x33,0x44} for( i=0; i<5; i++ ) { out[i] = hex2bin( in ); in += 2; } return 0; } 

Si la cadena es correcta y no es necesario mantener su contenido, entonces lo haría de esta manera:

 #define hex(c) ((*(c)>='a')?*(c)-'a'+10:(*(c)>='A')?*(c)-'A'+10:*(c)-'0') void hex2char( char *to ){ for(char *from=to; *from; from+=2) *to++=hex(from)*16+hex(from+1); *to=0; } 

EDIT 1: lo siento, me olvido de calcular con las letras AF (af)

EDIT 2: intenté escribir un código más pedante:

 #include  int xdigit( char digit ){ int val; if( '0' <= digit && digit <= '9' ) val = digit -'0'; else if( 'a' <= digit && digit <= 'f' ) val = digit -'a'+10; else if( 'A' <= digit && digit <= 'F' ) val = digit -'A'+10; else val = -1; return val; } int xstr2str( char *buf, unsigned bufsize, const char *in ){ if( !in ) return -1; // missing input string unsigned inlen=strlen(in); if( inlen%2 != 0 ) return -2; // hex string must even sized for( unsigned i=0; i 

Pruebas:

 #include  char buf[100] = "test"; void test( char *buf, const char *s ){ printf("%3i=xstr2str( \"%s\", 100, \"%s\" )\n", xstr2str( buf, 100, s ), buf, s ); } int main(){ test( buf, (char*)0 ); test( buf, "123" ); test( buf, "3x" ); test( (char*)0, "" ); test( buf, "" ); test( buf, "3C3e" ); test( buf, "3c31323e" ); strcpy( buf, "616263" ); test( buf, buf ); } 

Resultado:

  -1=xstr2str( "test", 100, "(null)" ) -2=xstr2str( "test", 100, "123" ) -3=xstr2str( "test", 100, "3x" ) -4=xstr2str( "(null)", 100, "" ) 1=xstr2str( "", 100, "" ) 3=xstr2str( "", 100, "3C3e" ) 5=xstr2str( "", 100, "3c31323e" ) 4=xstr2str( "abc", 100, "abc" ) 

Fatalfloor …

Hay un par de formas de hacerlo … primero, puede usar memcpy () para copiar la representación exacta en la matriz de caracteres.

También puede usar técnicas de cambio de bits y enmascaramiento de bits. Supongo que esto es lo que debes hacer ya que suena como un problema de tarea.

Por último, puede utilizar un direccionamiento de puntero elegante para copiar la ubicación de la memoria que necesita.

Todos estos métodos se detallan aquí:

Almacenar un int en una matriz char?

Dale una mejor manera:

Hexagonal a valor numérico, es decir, str [] = “0011223344” al valor 0x0011223344, use

 value = strtoul(string, NULL, 16); // or strtoull() 

hecho. si es necesario eliminar el comienzo de 0x00, ver abajo.

sin embargo, para LITTLE_ENDIAN plataformas, más: valor hexadecimal a matriz de caracteres, valor 0x11223344 a char arr [N] = {0x00, 0x11, …}

 unsigned long *hex = (unsigned long*)arr; *hex = htonl(value); // you'd like to remove any beginning 0x00 char *zero = arr; while (0x00 == *zero) { zero++; } if (zero > arr) memmove(zero, arr, sizeof(arr) - (zero - arr)); 

hecho.

Notas: Para convertir cadenas largas en 64 bits en un sistema de 32 bits, debe usar unsigned long long en lugar de unsigned long, y htonl no es suficiente, hágalo usted mismo como se muestra a continuación porque podría no haber htonll, htonq o hton64, etc.

 #if __KERNEL__ /* Linux Kernel space */ #if defined(__LITTLE_ENDIAN_BITFIELD) #define hton64(x) __swab64(x) #else #define hton64(x) (x) #endif #elif defined(__GNUC__) /* GNU, user space */ #if __BYTE_ORDER == __LITTLE_ENDIAN #define hton64(x) __bswap_64(x) #else #define hton64(x) (x) #endif #elif ... #endif #define ntoh64(x) hton64(x) 

ver http://effocore.googlecode.com/svn/trunk/devel/effo/codebase/builtin/include/impl/sys/bswap.h

 { char szVal[] = "268484927472"; char szOutput[30]; size_t nLen = strlen(szVal); // Make sure it is even. if ((nLen % 2) == 1) { printf("Error string must be even number of digits %s", szVal); } // Process each set of characters as a single character. nLen >>= 1; for (size_t idx = 0; idx < nLen; idx++) { char acTmp[3]; sscanf(szVal + (idx << 1), "%2s", acTmp); szOutput[idx] = (char)strtol(acTmp, NULL, 16); } } 

Estaba buscando lo mismo y después de leer mucho, finalmente creé esta función. Pensé que podría ayudar, alguien

 // in = "63 09 58 81" void hexatoascii(char *in, char* out, int len){ char buf[5000]; int i,j=0; char * data[5000]; printf("\n size %d", strlen(in)); for (i = 0; i < strlen(in); i+=2) { data[j] = (char*)malloc(8); if (in[i] == ' '){ i++; } else if(in[i + 1] == ' '){ i++; } printf("\n %c%c", in[i],in[i+1]); sprintf(data[j], "%c%c", in[i], in[i+1]); j++; } for (i = 0; i < j-1; i++){ int tmp; printf("\n data %s", data[i] ); sscanf(data[i], "%2x", &tmp); out[i] = tmp; } //printf("\n ascii value of hexa %s", out); } 

Digamos que esta es una plataforma ascii little-endian. Tal vez el OP significaba “array of char” en lugar de “string” … Trabajamos con pares de char y bit masking … note shiftyness of x16 ..

 /* not my original work, on stacko somewhere ? */ for (i=0;i < 4;i++) { char a = string[2 * i]; char b = string[2 * i + 1]; array[i] = (((encode(a) * 16) & 0xF0) + (encode(b) & 0x0F)); } 

y la función encode () se define ...

 unsigned char encode(char x) { /* Function to encode a hex character */ /**************************************************************************** * these offsets should all be decimal ..x validated for hex.. * ****************************************************************************/ if (x >= '0' && x <= '9') /* 0-9 is offset by hex 30 */ return (x - 0x30); else if (x >= 'a' && x <= 'f') /* af offset by hex 57 */ return(x - 0x57); else if (x >= 'A' && x <= 'F') /* AF offset by hex 37 */ return(x - 0x37); } 

Este enfoque flota en otros lugares, no es mi trabajo original, pero es viejo. No me gustaron los puristas porque no es portátil, pero la extensión sería trivial.

Primero, tu pregunta no es muy precisa. ¿Es la cadena una std::string o un búfer char ? ¿Configurado en tiempo de comstackción?

La memoria dinámica es casi seguro tu respuesta.

 char* arr = (char*)malloc(numberOfValues); 

Luego, puede recorrer la entrada y asignarla a la matriz.