Hex to char array in C

A line of hex values ​​is indicated, i.e., for example. "0011223344", so 0x00, 0x11, etc.

How to add these values ​​to char array?

It is equivalent to say:

char array[4] = { 0x00, 0x11 ... }; 
+9
c arrays char hex
source share
10 answers

You cannot fit 5 bytes of data into a 4-byte array; causing a buffer overflow.

If you have hexadecimal digits in a string, you can use sscanf() and a loop:

 #include <stdio.h> #include <ctype.h> 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); } 

Note that printing a line starting with a zero byte requires caution; most operations end on the first zero byte. Note that this code did not terminate the buffer zero; it is unclear whether null termination is desirable, and there is not enough space in the buffer that I declared to add a null terminal (but this is easily fixed). There is a good chance that if the code was packaged as a subroutine, it would need to return the length of the converted string (although you can also say that this is the length of the original string, divided by two).

+17
source share

If the string is correct and you do not need to save its contents, I would do it as follows:

 #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: sorry, I forgot to calculate using the letters AF (af)

EDIT 2: I tried to write more pedantic code:

 #include <string.h> 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<inlen; i++ ) if( xdigit(in[i])<0 ) return -3; // bad character in hex string if( !buf || bufsize<inlen/2+1 ) return -4; // no buffer or too small for( unsigned i=0,j=0; i<inlen; i+=2,j++ ) buf[j] = xdigit(in[i])*16 + xdigit(in[i+1]); buf[inlen/2] = '\0'; return inlen/2+1; } 

Testing:

 #include <stdio.h> 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 ); } 

Result:

  -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" ) 
+3
source share

I would do something like this:

 // 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; } 
+3
source share

I searched for the same thing, and after reading a lot, finally created this function. Thought it might help someone

 // 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); } 
+1
source share

Suppose this is a small ascii platform. Perhaps OP meant "char array" and not "string". We work with char pairs and bit masking .. note on x16 shift ..

 /* 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)); } 

and the encode () function is defined ...

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

This approach pops up elsewhere, this is not my original work, but it is outdated. Purists do not like it because it is not tolerated, but the extension will be trivial.

+1
source share

Fatalfloor ...

There are several ways to do this ... first, you can use memcpy () to copy the exact representation into a char array.

You can also use bit offset methods and bit masking methods. I guess this is what you need to do as it sounds like a home issue.

Finally, you can use some indirect pointer orientation to copy the desired memory location.

All of these methods are described in detail here:

Save int in char array?

0
source share

Give a better way:

Hex string for a numeric value, that is str [] = "0011223344" for the value 0x0011223344, use

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

done. if it is necessary to remove the beginning 0x00, see below.

although for platforms LITTLE_ENDIAN, plus: Hex value for char array, value 0x11223344 - 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)); 

done.

Notes: To convert a long string of 64 bits hex char arr to a 32-bit system, you should use unsigned long long instead of unsigned long, and htonl is not enough, so do it yourself, as shown below, because there is no htonll, htonq or 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) 

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

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

The best way I know:

 int hex2bin_by_zibri(char *source_str, char *dest_buffer) { char *line = source_str; char *data = line; int offset; int read_byte; int data_len = 0; while (sscanf(data, " %02x%n", &read_byte, &offset) == 1) { dest_buffer[data_len++] = read_byte; data += offset; } return data_len; } 

The function returns the number of converted bytes stored in dest_buffer. The input string may contain spaces and letters in mixed case.

"01 02 03 04 ab Cd eF garbage AB"

translates to dest_buffer containing 01 02 03 04 ab cd ef

as well as "01020304abCdeFgarbageAB"

translates as before.

The parsing stops at the first "error" (not hexadecimal, not space).

Note: this is also a valid string:

"01 2 03 04 ab Cd eF garbage AB"

and produces:

01 02 03 04 ab cd ef

0
source share

Firstly, your question is not very accurate. Is a string a std::string or char buffer? Installed at compile time?

Dynamic memory is almost certainly your answer.

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

Then you can go through the input and assign it to an array.

-4
source share

All Articles