十六进制转八进制|蓝桥杯

该文章描述了一个C++程序,用于将输入的十六进制数转换为八进制数。程序首先将十六进制转换为十进制,然后将十进制转换为八进制。在转换过程中,特别注意了不能有前导零的输出要求。作者遇到了不能用string作为函数返回值和不能返回数组的问题,并给出了使用memcpy的示例。
摘要由CSDN通过智能技术生成

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=""; 有的地方编译不通过

  • 3
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值