//编写函数htoi(),把由十六进制数字组成的字符串(包含可选前缀0X或0x)转换为与之等价的整型值,
//字符串中允许包含的数字为:0~9,a~f及A~F
#include <stdio.h>
#include <stdlib.h>
//该函数将字母(a~f,A~F)转换成相应的数字
int hexalpha_to_int(int c)
{
char hexalpha[] = "aAbBcCdDeEfF";
int i;
int answer = 0;
for(i = 0; answer == 0 && hexalpha[i] != '\0'; i++)
{
if(hexalpha[i] == c)
{
answer = 10 + (i / 2);
}
}
return answer;
}
unsigned int htoi(const char s[])
{
unsigned int answer = 0;
int i = 0;
int valid = 1;
int hexit;
if(s[i] == '0')//前缀0x,0X
{
++i;
if(s[i] == 'x' || s[i] == 'X')
{
++i;
}
}
while(valid && s[i] != '\0')
{
answer = answer * 16; //前一步的计算结果乘以16
if(s[i] >= '0' && s[i] <= '9')
{
answer = answer + (s[i] - '0');
}
else
{
hexit = hexalpha_to_int(s[i]);
if(hexit == 0) //遇到无法识别的字符,出错,停止计算
{
valid = 0;
}
else
{
answer = answer + hexit;
}
}
++i;
}
//遇到无法识别的字符,记为0
if(!valid)
{
answer = 0;
}
return answer;
}
/* Solution finished. This bit's just a test driver, so
* I've relaxed the rules on what's allowed.
*/
int main(void)
{
char *endp = NULL;
char *test[] =
{
"F00",
"bar",
"0100",
"0x1",
"0XA",
"0X0C0BE",
"abcdef",
"123456",
"0x123456",
"deadbeef",
"zog_c"
};
unsigned int result;
unsigned int check;
size_t numtests = sizeof test / sizeof test[0];//字符串指针的个数
size_t thistest; //size_t =unsigned int
for(thistest = 0; thistest < numtests; thistest++)
{
result = htoi(test[thistest]);
check = (unsigned int)strtoul(test[thistest], &endp, 16);//字符串转换成无符号整型数
if((*endp != '\0' && result == 0) || result == check)
{
printf("Testing %s. Correct. %u\n", test[thistest], result);
}
else
{
printf("Testing %s. Incorrect. %u\n", test[thistest], result);
}
}
return 0;
}
//strtoul()函数将字符串转换成无符号长整型数
//函数原型
//#include<stdlib.h>
//unsigned long int strtoul(const char *nptr,char **endptr,int base);
//strtoul()会将参数nptr字符串根据参数base来转换成无符号的长整型数。
//参数base范围从2至36,或0。参数base代表采用的进制方式,如base值为10则采用10进制,
//若base值为16则采用16进制数等。当base值为0时则是采用10进制做转换,
//但遇到如'0x'前置字符则会使用16进制做转换。一开始strtoul()会扫描参数nptr字符串,
//跳过前面的空格字符串,直到遇上数字或正负符号才开始做转换,
//再遇到非数字或字符串结束时('\0')结束转换,并将结果返回。
//若参数endptr不为NULL,则会将遇到不合条件而终止的nptr中的字符指针由endptr返回。