Description
给定n个十六进制正整数,输出它们对应的八进制数。
输入格式
输入的第一行为一个正整数n (1<=n<=10)。
接下来n行,每行一个由0~9、大写字母A~F组成的字符串,表示要转换的十六进制正整数,每个十六进制数长度不超过100000。
输出格式
输出n行,每行为输入对应的八进制正整数。
【注意】
输入的十六进制数不会有前导0,比如012A。
输出的八进制数也不能有前导0。
样例输入
2
39
123ABC
样例输出
71
4435274
【提示】
先将十六进制转换成十进制,再把十进制转换成八进制
代码
#include <iostream>
using namespace std;
int main()
{
int n;
cin>>n;
for(int i=0; i<n; i++)
{
string tow; //十进制的存储
string sixteen; //十六进制的存储
string eight; //八进制的存储
cin>>sixteen;
for(int j=0; j<sixteen.length(); j++) //十六进制转换成十进制
{
switch(sixteen[j])
{
case '0':tow+="0000";break;
case '1':tow+="0001";break;
case '2':tow+="0010";break;
case '3':tow+="0011";break;
case '4':tow+="0100";break;
case '5':tow+="0101";break;
case '6':tow+="0110";break;
case '7':tow+="0111";break;
case '8':tow+="1000";break;
case '9':tow+="1001";break;
case 'A':
case 'a':tow+="1010";break;
case 'B':
case 'b':tow+="1011";break;
case 'C':
case 'c':tow+="1100";break;
case 'D':
case 'd':tow+="1101";break;
case 'E':
case 'e':tow+="1110";break;
case 'F':
case 'f':tow+="1111";break;
}
}
//十进制转换成八进制 二进制转八进制是从右往左每3位按权相加,不足补0
if(tow.length()%3==1) //在转换之前先要确保它是3的整除数
tow="00"+tow;
if(tow.length()%3==2)
tow="0"+tow;
if(!(tow[0]=='0'&&tow[1]=='0'&&tow[2]=='0')) //拿出前三个来判断他们相加是不是等于0
{
char temp;
temp = (tow[0]-'0')*4+(tow[1]-'0')*2+tow[2];
eight += temp;
}
for(int j=3; j<tow.length(); j+=3)
{
eight+=(tow[j]-'0')*4+(tow[j+1]-'0')*2+tow[j+2];
}
cout<<eight<<endl;
}
return 0;
}
做题时出现的问题
转换进制最简单的方法是使用"iostream"库函数下的格式控制符dec、hex、oct。
int n;
cin>>hex>>n;
cout<<oct<<n;
表1:C++ 流操纵算子
流操纵算子 | 作 用 | |
*dec | 以十进制形式输出整数 | 常用 |
hex | 以十六进制形式输出整数 | |
oct | 以八进制形式输出整数 | |
fixed | 以普通小数形式输出浮点数 | |
scientific | 以科学计数法形式输出浮点数 | |
left | 左对齐,即在宽度不足时将填充字符添加到右边 | |
*right | 右对齐,即在宽度不足时将填充字符添加到左边 | |
setbase(b) | 设置输出整数时的进制,b=8、10 或 16 | |
setw(w) | 指定输出宽度为 w 个字符,或输人字符串时读入 w 个字符 | |
setfill(c) | 在指定输出宽度的情况下,输出的宽度不足时用字符 c 填充(默认情况是用空格填充) | |
setprecision(n) | 设置输出浮点数的精度为 n。 在使用非 fixed 且非 scientific 方式输出的情况下,n 即为有效数字最多的位数,如果有效数字位数超过 n,则小数部分四舍五人,或自动变为科学计 数法输出并保留一共 n 位有效数字。 在使用 fixed 方式和 scientific 方式输出的情况下,n 是小数点后面应保留的位数。 | |
setiosflags(flag) | 将某个输出格式标志置为 1 | |
resetiosflags(flag) | 将某个输出格式标志置为 0 | |
boolapha | 把 true 和 false 输出为字符串 | 不常用 |
*noboolalpha | 把 true 和 false 输出为 0、1 | |
showbase | 输出表示数值的进制的前缀 | |
*noshowbase | 不输出表示数值的进制.的前缀 | |
showpoint | 总是输出小数点 | |
*noshowpoint | 只有当小数部分存在时才显示小数点 | |
showpos | 在非负数值中显示 + | |
*noshowpos | 在非负数值中不显示 + | |
*skipws | 输入时跳过空白字符 | |
noskipws | 输入时不跳过空白字符 | |
uppercase | 十六进制数中使用 A~E。若输出前缀,则前缀输出 0X,科学计数法中输出 E | |
*nouppercase | 十六进制数中使用 a~e。若输出前缀,则前缀输出 0x,科学计数法中输出 e。 | |
internal | 数值的符号(正负号)在指定宽度内左对齐,数值右对 齐,中间由填充字符填充。 |
流操作算子的使用方法
使用这些算子的方法是将算子用 << 和 cout 连用。例如:
cout << hex << 12 << "," << 24;
本来想用两个函数分别转换,但是最后十进制转换成八进制的函数,发现不能用string作为函数返回值,也不能返回数组。
//网上找到函数返回数组的方法:直接把数组按照指针的方法传值,直接在函数里面改
int test(int *b)
{
int source[5]={[1]=2,[3]=4,[4]=-2};
memcpy(b,source,5*sizeof(int));
return 0;
}
int main(void)
{
int buf[5];
test(buf);
for(intt i = 0 ; i < 5 ; i++){
printf("buf[%d]=%d\n",i,buf[i]);
}
return 0;
}
一开始准备用十进制转换成十六进制的方法转换成八进制
但是目前没找到方法解决 输出的八进制数也不能有前导0
#include<iostream>
#include<string>
using namespace std;
//十六进制转十进制
long long a(string x){
int len=x.length();
long long sum=0;
for(int i=0;i<len;i++){
if(x[i]=='A')
sum=sum*16+10;
else if(x[i]=='B')
sum=sum*16+11;
else if(x[i]=='C')
sum=sum*16+12;
else if(x[i]=='D')
sum=sum*16+13;
else if(x[i]=='E')
sum=sum*16+14;
else if(x[i]=='F')
sum=sum*16+15;
else
sum=sum*16+(x[i]-'0');
}
return sum;
}
int main(){
int n;
cin>>n;
string str;
long long change10=0;
string change8[n];
for(int i=0;i<n;i++){
cin>>str;
change10=a(str);
int y;
if(change10==0){
cout<<0;
return 0;
}
while(change10>0){
y=change10%8;
change8[i]=char('0'+y)+change8[i];
change10=change10/8;
}
}
for(int i=0;i<n;i++){
cout<<change8[i]<<endl;
}
}
string初始化
string str;
不需要string str=""; 有的地方编译不通过