做一个能进行小数及负数的二 八 十 十六的进制转换,想必是许许多多大学大一上学期课程设计的热门选项,作为一个过来人让我们看看该程序的难点和坑究竟在哪?
首先 先了解一下进制转换的数学操作方法
好了上面就是进制转换的大致内容,如果需要更全面的进制转换的介绍,欢迎大家在博主的资源中下载学习进制转换的文章资料。
进制转化需要人性化的操作菜单(虽然是DOS风的)
1.输出操作菜单:
一级菜单:
(1)2进制数转换
(2)8进制数转换
(3)10进制数转换
(4)16进制数转换
(0)退出
二级菜单:(只是以2进制转其他进制为例,其他进制相同)
(1)2进制数 —> 8进制数
(2)2进制数 —> 10进制数
(3)2进制数 —> 16进制数
(0)返回上级目录
2.按选择,输入原进制数字符串
3.输出转换得到的目标进制数字符串
我们使用一个简单的while循环实现这样菜单
int _tmain(int argc, _TCHAR* argv[])
{
action=-1;
while(action!=0)
{
cout << "\n*************************\n";
cout << "1.二进制数转换\n";
cout << "2.八进制数转换\n";
cout << "3.十进制数转换\n";
cout << "4.十六进制数转换\n";
cout << "0.退出\n";
cout << "*************************\n";
while (action<0 || action>4)
{
cout << "请输入正确的功能号0-4:";
cin >> action ;
}
if(action==1)
{
fun1();
}
if(action==2)
{
fun2();
}
if(action==3)
{
fun3();
}
if(action==4)
{
fun4();
}
}
system("pause");
return 0;
}
这里我把菜单的主体写在了主函数里
不难发现这里有fun1 fun2 fun3 fun4 这四个我定义的函数,我以fun1为例给大家看一下
void fun1()
{
int action1=-1;
while(action1!=0)
{
cout << "\n*************************\n";
cout << "1.二进制数--->八进制数\n";
cout << "2.二进制数--->十进制数\n";
cout << "3.二进制数--->十六进制数\n";
cout << "0.返回上级目录\n";
cout << "*************************\n";
while (action1<0 || action1>3)
{
cout << "请输入正确的功能号0-3:";
cin >> action1 ;
}
if(action1==1)
{
fun108(fun210(a));
count_xiaoshu=0;
count_zhengfu=0;
action1=-1;
}
if(action1==2)
{
cout<<fun210(a);
count_xiaoshu=0;
count_zhengfu=0;
action1=-1;
}
if(action1==3)
{
fun1016(fun210(a));
count_xiaoshu=0;
count_zhengfu=0;
action1=-1;
}
if(action1==0)
{
action=-1;
}
}
}
结合上面两段代码,不难看出,菜单主要是通过while对键盘输入的action值进行判断实现的
而fun1等函数中则是根据需要引用了自定义的进制转换的有关函数。
进制转换函数的实例
我本人对于函数的名称并没有太多的考较 使用fun210表示二进制到十进制的转换 fun1610表示十六进制到十进制的转换、、 以此类推
而二转十六则是依靠二转十再使用十转十六实现的、、以此类推
下面我以fun210和fun1016为例给出代码
double fun210(char arr[])
{
cin>>arr;
int rongcuo;
for(rongcuo=0;rongcuo<50;rongcuo++)
{
if(arr[rongcuo]!='1'&&arr[rongcuo]!='0'&&arr[rongcuo]!='.'&&arr[rongcuo]!='\0'&&arr[rongcuo]!='-')
{
cout<<"wrong number,again"<<endl;
cin>>arr;
}
}
int len=strlen(arr);
check_xiaoshu(a);
check_zhengfu(a);
if(count_xiaoshu==0&&count_zhengfu==0)
{
int i;double sum=0;
for(i=len-1;i>=0;i--)
{
sum=sum+(arr[i]-48)*cifang(2,len-1-i);//乘以2的次方
}
return sum;
}
if(count_xiaoshu==0&&count_zhengfu==-1)
{
int i;double sum=0;
for(i=len-1;i>0;i--)
{
sum=sum+(arr[i]-48)*cifang(2,len-1-i);//乘以2的次方
}
return (sum*(-1));
}
if(count_xiaoshu==-1&&count_zhengfu==0)
{
int i;double sum=0;
for(i=check_xiaoshu(arr)-1;i>=0;i--)
{
sum=sum+(arr[i]-48)*cifang(2,check_xiaoshu(arr)-i-1);
}
for(i=check_xiaoshu(arr)+1;i<len;i++)
{
sum=sum+(arr[i]-48)*1.0/(cifang(2,i-check_xiaoshu(arr)));
}
return sum;
}
if(count_xiaoshu==-1&&count_zhengfu==-1)
{
int i;double sum=0;
for(i=check_xiaoshu(arr)-1;i>0;i--)
{
sum=sum+(arr[i]-48)*cifang(2,check_xiaoshu(arr)-i-1);
}
for(i=check_xiaoshu(arr)+1;i<len;i++)
{
sum=sum+(arr[i]-48)*1.0/(cifang(2,i-check_xiaoshu(arr)));
}
return sum*(-1);
}
}
当中的check_xiaoshu 及 check_zhengshu表示的是对字符串是否存在小数及是否为负数进行检测 。而rongcuo则是表示容错机制,当用户输入非法字符时可以进行报错处理
void fun1016(double m)
{
if(m<0)
{
count_zhengfu=-1;
m=m*(-1);
}
int zhengshu;
char zheng[50]={0};
double xiaoshu;
char xiao[50]={0};
int mm;
mm=(int)m;
zhengshu=mm;
if(mm==m)// zhe shi yi ge fei xiao shu!!!!
{
int i=0;
do
{
zheng[i]=zhengshu%16+48;
zhengshu=zhengshu/16;
i++;
}while(zhengshu!=0);
int k;
for(k=0;k<50;k++)
{
if(zheng[k]==58)
zheng[k]='A';
if(zheng[k]==59)
zheng[k]='B';
if(zheng[k]==60)
zheng[k]='C';
if(zheng[k]==61)
zheng[k]='D';
if(zheng[k]==62)
zheng[k]='E';
if(zheng[k]==63)
zheng[k]='F';
}
if(count_zhengfu==-1)
{
cout<<'-';
}
for(;i>=0;i--)
{
cout<<zheng[i];
}
}
if(mm!=m)//zhe ge shu you xiao shu!!!!
{
int i=0;
xiaoshu=m-mm;
do
{
zheng[i]=zhengshu%16+48;
zhengshu=zhengshu/16;
i++;
}while(zhengshu!=0);
int k;
for(k=0;k<50;k++)
{
if(zheng[k]==58)
zheng[k]='A';
if(zheng[k]==59)
zheng[k]='B';
if(zheng[k]==60)
zheng[k]='C';
if(zheng[k]==61)
zheng[k]='D';
if(zheng[k]==62)
zheng[k]='E';
if(zheng[k]==63)
zheng[k]='F';
}
if(count_zhengfu==-1)
{
cout<<"-";
}
for(i=strlen(zheng)-1;i>=0;i--)
{
cout<<zheng[i];
}
cout<<".";
for(i=0;i<6;i++)// xiaoshu bufen baoliu 6 wei!!!
{
xiao[i]=(int)(xiaoshu*16)+48;
xiaoshu=xiaoshu*16-(int)(xiaoshu*16);
}
for(k=0;k<6;k++)
{
if(xiao[k]==58)
xiao[k]='A';
if(xiao[k]==59)
xiao[k]='B';
if(xiao[k]==60)
xiao[k]='C';
if(xiao[k]==61)
xiao[k]='D';
if(xiao[k]==62)
xiao[k]='E';
if(xiao[k]==63)
xiao[k]='F';
}
for(i=0;i<6;i++)
{
cout<<xiao[i];
}
}
}
正负小数的检测
int count_xiaoshu=0;// -1||0
int count_zhengfu=0;//-1||0
使用一个int作为flag 再对字符串进行遍历检测“-” “.”就很方便地实现了
个人认为的坑
进行进制转换必不可免的需要使用到字符数组,而使用字符数组时 置零这一环节至关重要,要不然就像这样
前面有正解,后面一堆乱码。。
总结
进制转换的介绍 到这里就结束了 如果有需要的童鞋 可以到我的资源里下载源码哦(vs2019文件)进制转换源码