人总要战胜内心的懦弱的,我不能一直这么缩在里边。终究向自己发出了挑战,还是会伤心的时候,发愣的时候。如果可以,我也希望像盗梦空间的女主一直沉在两个人的梦里永远不要醒来。可是,我们谁又能抗拒时间呢?这雨猛烈的下,下了一天,有时候突然好大的打雷声,有点怕。还是晴吧,天晴了,阳光灿烂的多好啊
一.题目:从键盘输入一个字符串,去掉所有非十六进制字符后转换成十进制数输出。读懂以下main函数,编
写相应的函数del16和htod。
1 #include<stdio.h> 2 #include<string.h> 3 void main() 4 { 5 char s1[10],s2[10]; 6 void del16(char *p1,char *p2); 7 long htod(char *p); 8 gets(s1); //读入一字符串 9 del16(s1,s2); //去掉所有非十六进制字符到s2 10 printf("%d\n",htod(s2)); //把s2转换为10进制 11 }
二.思路 :十六进制字符指的是0~f或者大写0~F的字符
将字符串中0~f或者大写0~F的字符存到另一个字符数组里
将十六进制字符转换成十进制数输出
三.程序
1 #include <stdio.h> 2 3 int main(void) 4 { 5 char s1[10],s2[10]; 6 void del16(char *p1,char *p2); 7 long htod(char *p); 8 gets(s1); //读入一字符串 9 del16(s1,s2); //去掉所有非十六进制字符到s2 10 printf("%s",s2); 11 printf("%d\n",htod(s2)); //把s2转换为10进制 12 13 return 0; 14 } 15 16 void del16(char *p1,char *p2) 17 { 18 while(*p1) 19 { 20 if((*p1 >='0' && *p1<='9')||(*p1>='a' && *p1<='f')||(*p1>='A' && *p1<='F')) 21 { 22 *p2=*p1; 23 p2++; 24 } 25 p1++; 26 27 } 28 29 } 30 31 long htod(char *p) 32 { 33 int sum = 0; 34 while(*p) 35 { 36 if(*p>='0'&&*p<='9') 37 sum = sum*10 + (*p-'0'); 38 else if(*p>='a' &&*p<='f') 39 sum = sum*10 + (*p-'a'+10); 40 else if(*p>='A' && *p<='F') 41 sum = sum*10 + (*p-'A'+10); 42 } 43 return sum; 44 }
四.编译运行
从结果可以看出,s2的获取出了问题,后面那一串“烫烫?23abwxydf”怎么出来的?
五.分析问题
1.检查函数del16(char *p1,char *p2),发现指向字符型数据的指针p2在结尾处没有添加字符串结束符‘\0’,记住,这是字符串,获取的字符串,要人为的添加结束符
1 void del16(char *p1,char *p2) 2 { 3 while(*p1) 4 { 5 if((*p1 >='0' && *p1<='9')||(*p1>='a' && *p1<='f')||(*p1>='A' && *p1<='F')) 6 { 7 *p2=*p1; 8 p2++; 9 } 10 p1++; 11 *p2 = '\0'; 12 13 } 14 15 }
2.在十六进制转换成十进制时,'0'~'9'是小于10的数,sum的权重是10。但是'a'~'f'肯定是大于10的数,也就是两位数了,那么sum的权重就不该是10了,而应该是100才对。 另外,还有个地方被忽略了,就是指针的移动:忘了p++。这个地方已经不止一次被我给漏掉了,要引以为戒。
1 long htod(char *p) 2 { 3 int sum = 0; 4 while(*p) 5 { 6 if(*p>='0'&&*p<='9') 7 sum = sum*10 + (*p-'0'); 8 else if(*p>='a' &&*p<='f') 9 sum = sum*100 + (*p-'a'+10); 10 else if(*p>='A' && *p<='F') 11 sum = sum*100 + (*p-'A'+10);
p++; 12 } 13 return sum; 14 }
六.改进
1 #include <stdio.h> 2 3 int main(void) 4 { 5 char s1[10],s2[10]; 6 void del16(char *p1,char *p2); 7 long htod(char *p); 8 gets(s1); //读入一字符串 9 del16(s1,s2); //去掉所有非十六进制字符到s2 10 printf("%s\n",s2); 11 printf("%d\n",htod(s2)); //把s2转换为10进制 12 13 return 0; 14 } 15 16 void del16(char *p1,char *p2) 17 { 18 while(*p1) 19 { 20 if((*p1 >='0' && *p1<='9')||(*p1>='a' && *p1<='f')||(*p1>='A' && *p1<='F')) 21 { 22 *p2=*p1; 23 p2++; 24 } 25 p1++; 26 *p2 = '\0'; 28 } 29 30 } 31 32 long htod(char *p) 33 { 34 int sum = 0; 35 while(*p) 36 { 37 if(*p>='0'&&*p<='9') 38 sum = sum*10 + (*p-'0'); 39 else if(*p>='a' &&*p<='f') 40 sum = sum*100 + (*p-'a'+10); 41 else if(*p>='A' && *p<='F') 42 sum = sum*100 + (*p-'A'+10); 43 p++; 44 } 45 return sum; 46 }
七.编译运行
这是肿么回事?
八.贴出网上解答方法
#include<stdio.h> #include<string.h> void main() { char s1[10],s2[10]; void del16(char *p1,char *p2); long htod(char *p); gets(s1); //读入一字符串 del16(s1,s2); //去掉所有非十六进制字符到s2 printf("%d\n",htod(s2)); //把s2转换为10进制 } void del16(char *p1,char *p2) { while(*p1) { if(*p1<='f'&&*p1>='a'||*p1<='F'&&*p1>='A'||*p1<='9'&&*p1>='0') *p2++=*p1; p1++; } *p2='\0'; } long htod(char *p) { long sum=0; while(*p) { if(*p<='f'&&*p>='a') sum=sum*16+*p-'a'+10; else if(*p<='F'&&*p>='A') sum=sum*16+*p-'A'+10; else if(*p<='9'&&*p>='0') sum=sum*16+*p-'0'; p++; } return sum; }
九.对比了网上的解答
1.很显然在换算时由于是16进制换算成十进制,所以sum理所当然的权重为16而不是10或者100。但问题是,用
10或者100怎么会出现上面那种溢出的情况呢?
2.在函数del16(char *p1,char *p2)里,直接p2 = p1有什么不可以的?这和*p2 = *p1有区别吗?