输入一个以#结束的字符串,本题要求滤去所有的非十六进制字符(不分大小写),组成一个新的表示十六进制数字的字符串,然后将其转换为十进制数后输出。如果在第一个十六进制字符之前存在字符“-”,则代表该数是负数。
输入格式:
输入在一行中给出一个以#结束的非空字符串。
输出格式:
在一行中输出转换后的十进制数。题目保证输出在长整型范围内。

分析:
首先咱要知道十六进制字符包括 '0'~'9' 和 'a'~'f' 以及 'A'~'F'
其中'a'代表10,a~f依次为10、11、12、13、14、15;而且十六进制由 中每位数依次向左乘以16
从十六进制字符转换成十进制数: (设该十进制数的结果用变量number接收)
如果是数字字符:number = number * 16 + b[j]-'0';
/*要输出一个十进制数,就要把位数一位一位的向后推,从个位,到十位,到百位...当然对于十六进制来说,要进位可不是乘以10咯,而是乘以16哦,而b[j]-'0'则是将字符转换成数字*/
如果是小写英文字母:number = number * 16 + b[j] - 'a' + 10;
/*这里和数字字符唯一不同的是后面还要加10,这是为啥捏?注意字母a 是代表10哦,假设b[j]='a',那么b[j]-'a'=0了不是?所以要加上10呢 */
如果是大写英文字母:number = number * 16 + b[j] - 'A' + 10;/*大写字母同理*/
代码如下:
#include<stdio.h>
int main(void)
{
//思路:输入#结尾的字符串、找出十六进制字符、存储、转换成十进制、输出
char a[80], b[80]; //定义a[80]数组来存储输入的字符串,b[80]数组来存储过滤后的十六进制数组
int i,flag=1,number=0,j=0,k,k1; // k表示'-'的位置,k1表示第一个十六进制字符的位置
i = 0;
while ((a[i]=getchar())!= '#') { //输入#结尾的字符串
i++;
}
a[i] = '\0';
for (i = 0; a[i] != '\0'; i++) { //找出k
if (a[i] == '-') {
k = i;
break;
}
}
for (i = 0; a[i] != '\0'; i++) { //找出k1
if ((a[i] >= '0' && a[i] <= '9') || (a[i] >= 'a' && a[i] <= 'f') || (a[i] >= 'A' && a[i] <= 'F')) {
k1 = i;
break;
}
}
if (k<k1) { //如果第一个十六进制之前输入-,代表负数
flag = 0;
}
i = 0; //找出十六进制字符
while (a[i] != '\0') {
if ((a[i] >= '0' && a[i] <= '9') || (a[i] >= 'a' && a[i] <= 'f')||(a[i]>='A'&&a[i]<='F')) {
b[j] = a[i];
j++;
}
i++;
}
b[j] = '\0';
for (j = 0; b[j] != '\0'; j++) { //转换成十进制
if (b[j] >= '0' && b[j] <= '9') { //如果是数字
number = number * 16 + b[j]-'0';
}
else if (b[j] >= 'a' && b[j] <= 'f') { //如果是小写字母
number = number * 16 + b[j] - 'a' + 10;
}
else if (b[j] >= 'A' && b[j] <= 'F') { //如果是大写字母
number = number * 16 + b[j] - 'A' + 10;
}
}
if (flag == 0) { //如果是负数,则将前面的正数的结果转换成负数
number = -number;
}
printf("%d", number); //输出结果
return 0;
}
运行结果:

以上仅是我个人的思考,如若有误,欢迎指正!