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);
然后,您可以遍历输入,并将其分配给数组。