基础练习 十六进制转八进制

问题描述

给定n个十六进制正整数,输出它们对应的八进制数。

输入格式

输入的第一行为一个正整数n (1<=n<=10)。
接下来n行,每行一个由0-9、大写字母A-F组成的字符串,表示要转换的十六进制正整数,每个十六进制数长度不超过100000。

输出格式

输出n行,每行为输入对应的八进制正整数。
【注意】
输入的十六进制数不会有前导0,比如012A。
输出的八进制数也不能有前导0。

样例输入

2
39
123ABC

样例输出

71   
4435274

知识点
  • C 库中函数 size_t strlen(const char *str) 计算字符串 str 的长度,直到空结束字符,但不包括空结束字符
  • 字符-‘0’-------将字符转换为数值;
    数值+‘0’-------将数值转换为字符
  • ASCII码表
  • 进制转换
  • ‘\0’是字符串的结束符号(b[len]=’\0’意义?)
  • 前导0在哪?
  • 数组为什么要设置这么大?
思考过程

十六转二再转八
十六转十再转八(但是可能溢出?)

代码(参考)
#include 
#include 
char h[100002],b[400008],e[400008]; //十六、二、八int main()
{int n;scanf("%d",&n);   //输入待换的十六进制数总数while(n--)  //逐一处理这些十六进制数,16转2再转8{scanf("%s",h);  int i,len=0;  //len是之后转化成的二进制数长度for(i=strlen(h)-1;i>=0;i--) /*对输入的十六进制数从右往左进行处理<- -,for循环结束时会得到完成的b数组存储着输入十六进制数的二进制表示*/{int v,j;   //v用于存储十六进制数每位的值(如该位为'A' 则v=10)if(h[i]>='0'&& h[i]<='9')   //0~9(16)v=h[i]-'0';  //将字符转换为数值再赋给velse  //A~F(16)v=h[i]-'A'+10; /*h[i]-'A'将字符转换为数值后与10相加,例:h[5]='C', 'C'-'A'=2, v=2+10=12*/for(j=0;j<4;j++)  //用4位的二进制表示一位十六进制{b[len++]=v%2+'0';  //v%2为值,加上‘0’可转化为字符v/=2;}}b[len]='\0';  //最高位补0无影响(终止符?没看出啥用)int x=0,cnt=1,l=0;  //x记录每次得到的八进制的值,cnt为位权数for(i=0;i<len;i++)  {if(cnt==4||i==len-1)  /*每三位二进制数转换成一个八进制数,所以每三位要存储一次得到的八进制数,同时将权数重置。当得到的二进制数长度不能恰好是三的倍数时,最后一组二进制数就不会得到cnt==4的条件,所以要加上另一个条件i==len-1,表示这是最后一组需要存储的八进制数,将得到的八进制数赋给x存储在e数组中。*/{x=cnt*(b[i]-'0')+x;  //110转换为八进制:1*4+1*2+0*1=6cnt=1;e[l++]=x+'0';x=0;  //注意x清零,每3位整体计算一位数(八进制)}else{x=cnt*(b[i]-'0')+x;   cnt*=2;}}i=l-1;  while(i>=0&&e[i]=='0')   //为什么要消除前导0?哪有前导0?i--;if(i<0)   //输入为0的情况printf("0");for(;i>=0;i--)   //倒序输出八进制数组{printf("%c",e[i]);}printf("\n");}return 0;
}


本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!

相关文章

立即
投稿

微信公众账号

微信扫一扫加关注

返回
顶部