在C中有效地将hex字符串转换为整数?

在C中,将hex数字字符串转换为二进制unsigned intunsigned long的最有效方法是什么?

例如,如果我有0xFFFFFFFE ,我想要一个带有base10值4294967294int

你想要strtolstrtoul 。 另请参见Unix手册页

编辑: 现在与MSVC,C ++和非GNU编译器兼容(参见结束)。

问题是“最有效的方式”。 OP没有指定平台,他可以编译基于RISC的ATMEL芯片,其代码具有256字节的闪存。

对于记录,以及那些(像我一样),欣赏“最简单的方式”和“最有效的方式”之间的区别,以及谁喜欢学习…

 static const long hextable[] = { [0 ... 255] = -1, // bit aligned access into this table is considerably ['0'] = 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, // faster for most modern processors, ['A'] = 10, 11, 12, 13, 14, 15, // for the space conscious, reduce to ['a'] = 10, 11, 12, 13, 14, 15 // signed char. }; /** * @brief convert a hexidecimal string to a signed long * will not produce or process negative numbers except * to signal error. * * @param hex without decoration, case insensitive. * * @return -1 on error, or result (max (sizeof(long)*8)-1 bits) */ long hexdec(unsigned const char *hex) { long ret = 0; while (*hex && ret >= 0) { ret = (ret << 4) | hextable[*hex++]; } return ret; } 

它不需要外部库,而且应该非常快。 它处理大写,小写,无效字符,奇数大小的hex输入(例如:0xfff),最大大小仅受编译器限制。

对于不接受花式hextable声明的非GCC或C ++编译器或编译器。

用这个(更长,但更符合)版本替换第一个语句:

 static const long hextable[] = { -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, -1,-1, 0,1,2,3,4,5,6,7,8,9,-1,-1,-1,-1,-1,-1,-1,10,11,12,13,14,15,-1, -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, -1,-1,10,11,12,13,14,15,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1 }; 

试试这个:

 #include  int main() { char s[] = "fffffffe"; int x; sscanf(s, "%x", &x); printf("%u\n", x); } 

如果你没有stdlib,那么你必须手动完成。

 unsigned long hex2int(char *a, unsigned int len) { int i; unsigned long val = 0; for(i=0;i 

注意:此代码假定为大写AF。 如果len超出最长的32或64位整数,并且非法的hex字符没有错误捕获,则它不起作用。

好像经常发生一样,你的问题会遇到严重的术语错误/含糊不清。 在通常的演讲中,它通常无关紧要,但在这个特定问题的背景下,它是至关重要的。

你看,没有“hex值”和“十进制值”(或“hex数”和“十进制数”)这样的东西。 “hex”和“十进制”是值表示的属性。 同时,值(或数字)本身没有表示,因此它们不能是“hex”或“十进制”。 例如,C语法中的0xF15相同数字的两个不同表示

我猜你的问题,即它的陈述方式,表明你需要将一个值的ASCIIhex表示(即一个字符串)转换为一个值的ASCII十进制表示(另一个字符串)。 一种方法是使用整数表示作为中间表示:首先,将ASCIIhex表示转换为足够大小的整数(使用strto... group中的函数,如strtol ),然后将整数转换为ASCII十进制表示(使用sprintf )。

如果这不是你需要做的,那么你必须澄清你的问题,因为你不可能从你的问题的制定方式中弄清楚。

@Eric

为什么有效的代码解决方案会被拒绝? 当然,它很丑陋,可能不是最快的方式,但说“strtol”或“sscanf”更有启发性。 如果您亲自尝试,您将了解一些有关如何在幕后发生的事情。

我不认为你的解决方案应该被拒绝,但我猜测为什么会发生这种情况是因为它不太实际。 投票的想法是,“最佳”答案将浮动到顶部,虽然你的答案可能对引擎盖下发生的事情(或可能发生的方式)更有启发性,但它绝对不是解析hex数字的最佳方法在生产系统中。

同样,从教育的角度来看,我认为你的答案没有任何问题,我当然不会(也没有)投票。 不要气馁,不要因为有些人不喜欢你的答案而停止发帖。 它发生了。

我怀疑我的回答会让你觉得自己被选中投票感觉更好,但我知道当你问为什么某些事情被投票失败而没有人回答时,这一点尤其不好玩。

对于较大的Hex字符串,如示例中我需要使用strtoul 。

hex到十进制。 不要在在线编译器上运行它,因为它不起作用。

 #include void main() { unsigned int i; scanf("%x",&i); printf("%d",i); } 

对于AVR微控制器,我编写了以下函数,包括相关注释以使其易于理解:

 /** * hex2int * take a hex string and convert it to a 32bit number (max 8 hex digits) */ uint32_t hex2int(char *hex) { uint32_t val = 0; while (*hex) { // get current character then increment char byte = *hex++; // transform hex character to the 4bit equivalent number, using the ascii table indexes if (byte >= '0' && byte <= '9') byte = byte - '0'; else if (byte >= 'a' && byte <='f') byte = byte - 'a' + 10; else if (byte >= 'A' && byte <='F') byte = byte - 'A' + 10; // shift 4 to make space for new digit, and add the 4 bits of the new digit val = (val << 4) | (byte & 0xF); } return val; } 

例:

 char *z ="82ABC1EF"; uint32_t x = hex2int(z); printf("Number is [%X]\n", x); 

将输出: 在此处输入图像描述

为什么有效的代码解决方案会被拒绝? 当然,这很难看……

也许是因为它既丑陋又不教育, 不起作用。 另外,我怀疑像我一样,大多数人目前没有编辑的权力(并且根据所需的等级判断 – 永远不会)。

使用数组可以提高效率,但这段代码中没有提到。 它也不考虑大小写,因此它不适用于问题中提供的示例。 FFFFFFFE

@Eric

我实际上希望看到一个C向导发布一些非常酷的东西,有点像我做的但是不那么冗长,同时仍然“手动”做。

好吧,我不是C大师,但这就是我想出来的:

 unsigned int parseHex(const char * str) { unsigned int val = 0; char c; while(c = *str++) { val <<= 4; if (c >= '0' && c <= '9') { val += c & 0x0F; continue; } c &= 0xDF; if (c >= 'A' && c <= 'F') { val += (c & 0x07) + 9; continue; } errno = EINVAL; return 0; } return val; } 

我原本有更多的bitmasking继续而不是比较,但我严重怀疑bitmasking比现代硬件上的比较更快。

尝试将此值从十进制转换为hex

  #include #include int main(void) { int count=0,digit,n,i=0; int hex[5]; clrscr(); printf("enter a number "); scanf("%d",&n); if(n<10) { printf("%d",n); } switch(n) { case 10: printf("A"); break; case 11: printf("B"); break; case 12: printf("B"); break; case 13: printf("C"); break; case 14: printf("D"); break; case 15: printf("E"); break; case 16: printf("F"); break; default:; } while(n>16) { digit=n%16; hex[i]=digit; i++; count++; n=n/16; } hex[i]=n; for(i=count;i>=0;i--) { switch(hex[i]) { case 10: printf("A"); break; case 11: printf("B"); break; case 12: printf("C"); break; case 13: printf("D"); break; case 14: printf("E"); break; case 15: printf("F"); break; default: printf("%d",hex[i]); } } getch(); return 0; } 
 #include "math.h" #include "stdio.h" /////////////////////////////////////////////////////////////// // The bits arg represents the bit say:8,16,32... ///////////////////////////////////////////////////////////// volatile long Hex_To_Int(long Hex,char bits) { long Hex_2_Int; char byte; Hex_2_Int=0; for(byte=0;byte 

在C中,您可以通过多种方式将hex数转换为十进制数。 一种方法是将hex数转换为整数。 我个人认为这很简单。

这是一个示例代码,用于在铸造的帮助下将hex数转换为十进制数。

 #include  int main(){ unsigned char Hexadecimal = 0x6D; //example hex number int Decimal = 0; //decimal number initialized to 0 Decimal = (int) Hexadecimal; //conversion printf("The decimal number is %d\n", Decimal); //output return 0; } 

目前这只适用于小写,但它非常容易使它适用于两者。

 cout << "\nEnter a hexadecimal number: "; cin >> hexNumber; orighex = hexNumber; strlength = hexNumber.length(); for (i=0;i="0") && (hexa<="9")) { //cout << "This is a numerical value.\n"; } else { //cout << "This is a alpabetical value.\n"; if (hexa=="a"){hexa="10";} else if (hexa=="b"){hexa="11";} else if (hexa=="c"){hexa="12";} else if (hexa=="d"){hexa="13";} else if (hexa=="e"){hexa="14";} else if (hexa=="f"){hexa="15";} else{cout << "INVALID ENTRY! ANSWER WONT BE CORRECT\n";} } //convert from string to integer hx = atoi(hexa.c_str()); finalhex = finalhex + (hx*pow(16.0,strlength-i-1)); } cout << "The hexadecimal number: " << orighex << " is " << finalhex << " in decimal.\n";