C中的hex到char数组

给定一串hex值,例如“0011223344”,使其为0x00,0x11等。

如何将这些值添加到char数组?

相当于:

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

您不能将5个字节的数据放入4字节数组中; 这会导致缓冲区溢出。

如果字符串中有hex数字,则可以使用sscanf()和循环:

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

请注意,打印以零字节开头的字符串需要小心; 大多数操作在第一个空字节上终止。 请注意,此代码没有空终止缓冲区; 目前尚不清楚是否需要空终止,并且我声明的缓冲区中没有足够的空间来添加一个终端null(但很容易修复)。 如果将代码打包为子例程,则需要返回已转换字符串的长度(尽管您也可以认为它是源字符串的长度除以2)。

我会做这样的事情;

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

如果字符串是正确的,不需要保留其内容,那么我会这样做:

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

编辑1:对不起,我忘了用字母AF(af)来计算

编辑2:我试着写一个更迂腐的代码:

 #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 

测试:

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

结果:

  -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 …

有几种方法可以做到这一点……首先,您可以使用memcpy()将精确表示复制到char数组中。

您也可以使用位移和位屏蔽技术。 我猜这是你需要做的,因为它听起来像一个家庭作业问题。

最后,您可以使用一些花哨的指针间接来复制所需的内存位置。

所有这些方法都在这里详述:

将int存储在char数组中?

给出最好的方法:

hex字符串到数值,即str [] =“0011223344”到值0x0011223344,使用

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

完成。 如果需要删除开头0x00,请参阅下文。

虽然对于LITTLE_ENDIAN平台,加上:hex值到char数组,值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)); 

完成。

注意:为了在32位系统上将长字符串转换为64位hex字符,你应该使用无符号long long而不是unsigned long,并且htonl是不够的,所以自己如下所示,因为可能没有htonll,htonq或者hton64等:

 #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) 

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

我正在寻找相同的东西,经过阅读后,终于创建了这个function。 有人认为这可能有所帮助

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

让我们说这是一个小端ascii平台。 也许OP意味着“数组的字符”而不是“字符串”..我们使用成对的字符和位屏蔽..注意x16的shiftyness ..

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

和函数encode()定义了......

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

这种方法漂浮在其他地方,这不是我原来的工作,但它已经过时了。 纯粹主义者不喜欢它,因为它是不可移植的,但扩展将是微不足道的。

首先,你的问题不是很精确。 字符串是std::string还是char缓冲区? 在编译时设置?

动态记忆几乎肯定是你的答案。

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

然后,您可以遍历输入,并将其分配给数组。