#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <conio.h>
void work(); //驱动函数
int Menu(); //菜单函数
void AnytoAny(); //任意进位制转换为任意进位制
void ConversionTable(); //任意进位制转换为常用进位制表
void DecimaltoAny(double m,int n); //十进制转换为任意进位制
double AnytoDecimal(char str[],int n); //任意进位制转换为十进制
double t3;
int n,m;
char str[100];
int main()
{
printf("\n\n\n\n\n\n\n\n\n");
printf(" +----------------------+\n");
printf(" + 欢迎使用进位制转换器 +\n");
printf(" +----------------------+\n");
printf(" 请按任意键开始!");
getch();
system("cls");
work();
return 0;
}
void work()
{
int Choice;
do
{
Choice=Menu(); //从菜单中获得功能代码
switch(Choice)
{
case '1':
AnytoAny();
break;
case '2':
ConversionTable();
case '0':
{
system("cls");
printf("\n\n\n\n\n\n\n\n\n\n");
printf(" 欢迎您再次使用! \n");
}
}
getch();
system("cls");
}
while(Choice!='0');
}
int Menu()
{
char c;
while(1)
{
printf("\n\n\n\n\n\n\n");
printf(" +----------------------------+\n");
printf(" + 1任意进位置间的转换 +\n");
printf(" + 2常用进位置转换表 +\n");
printf(" + 0退出程序 +\n");
printf(" +----------------------------+\n");
printf("\n 请输入操作指令:");
c=getch();
if(c>='0'&&c<='2')
break;
else
{
system("cls");
printf(" 请重新选择功能!\n\n");
}
}
return c;
}
void AnytoAny()
{
system("cls"); //开始时清屏
printf("请输入待转换数的进制:\n");
scanf("%d",&n);
printf("请输入待转换的数:\n");
getchar(); //消除回车影响
gets(str);
printf("请输入将转换的进位制:\n");
scanf("%d",&m);
t3=AnytoDecimal(str,n); //将输入字符串转换为十进制
printf("转换为%d进制数为:\n",m);
DecimaltoAny(t3,m); //循环将转换后的十进制转换为m进制
getch();
}
void ConversionTable()
{
int i;
system("cls"); //开始时清屏
printf("请输入待转换数的进制:\n");
scanf("%d",&n);
printf("请输入待转换的数:\n");
getchar(); //消除回车影响
gets(str);
t3=AnytoDecimal(str,n); //将输入字符串转换为十进制
for(i=2; i<17; i+=2) //循环将转换后的十进制转换为2,4,6,8,10,12,14,16进制
{
printf("%d进置:\n",i);
DecimaltoAny(t3,i);
printf("\n");
}
printf("32进置:\n");
DecimaltoAny(t3,32);
printf("\n64进置:\n");
DecimaltoAny(t3,64);
getch();
}
void DecimaltoAny(double m,int n)
{
int i=0,j,a,num[99999];
double b=0;
char ch[99999]= {'\0'};
a=(int)m;
do //用除n取余法获得小数点前的n进制的每一位
{
num[i]=a%n;
if(num[i]>=10)
ch[i]='A'+num[i]-10;
a=a/n;
i++;
}
while(a!=0);
for(j=i-1; j>=0; j--) //输出整数部分n进制的每一位
{
if(ch[j]=='\0')
printf("%d",num[j]);
else
printf("%c",ch[j]);
}
printf("."); //小数点单独输出
int sh[99999]= {0};
b=m-(int)m;
i=0;
do //用乘n取整法获取小数点后n进制的每一位
{
num[i]=(int)(b*n);
if(num[i]>=10)
sh[i]=65+num[i]-10;
b=b*n-num[i];
i++;
}
while(b!=0);
for(j=0; j<i; j++) //输出小数部分n进制的每一位
{
if(sh[j]==0)
printf("%d",num[j]);
else
printf("%c",sh[j]);
}
}
double AnytoDecimal(char str[],int n)
{
long t1;
int i,t,len;
int j = 0,k=0; /* 声明几个整形变量,下面要用到 */
char lis[1000][1000],a[1000]= {0},b[1000]= {0}; /* 这个是用于存储分离后的各个字符串,二维数组,最多分离出100个字符串,每个字符串的元素最多100个 */
memset(lis,0,sizeof(lis)); /* 使用memset函数,对list中的所有元素赋值为0,sizeof(list)是用于获取list的总占用空间 */
int l=strlen(str);
for(i=0; i<l; ++i) /* for循环,从0开始,每次循环后,i自增,循环条件是i必须小于str的长度,否则退出循环 */
{
if(str[i] == '.') /* 如果str中的第i个字符为逗号 */
{
lis[j][k] = 0; /* 分离出的第j个字符串中的第k个字符为0,也就是字符串的结束符 */
++j; /* j自增,这就是表示下一个被分离出的字符串的序号 */
k = 0; /* 因为要将字符写到下个被分离出的字符串中,所以要从0开始 */
}
else /* 否则,不是逗号 */
{
lis[j][k] = str[i]; /* 二维数组list中的第j个字符串的第k个字符是符串str中的第i个字符 */
++k; /* 切换到下一个字符 */
}
}
l=strlen(lis[0]);
int w=strlen(lis[1]);
for(i=0; i<l; i++) //将小数点之前部分用字符数组a保存
a[i]=lis[0][i];
for(i=0; i<w; i++) //将小数点之后部分用字符数组b保存
b[i]=lis[1][i];
strupr(a); //将数组中的小写字母转化为大写字母
len = strlen(a); //求出数组的长度
t1 = 0;
for(i=0; i<len ; i++)
{
if((a[i] - '0' >= n && a[i] < 'A') || a[i] - 'A' + 10 >n ) //判断输入的数据和进制数是否符合
{
printf("data error!!\n"); //错误
exit (0);
}
if(a[i] >='0' && a[i] <= '9') //判断是否为数字
t = a[i] - '0'; //求出该数字赋值给t
else if (n >=11 && (a[i] >= 'A' && a[i] <= 'A' +n -10)) //判断是否为字母
t = a[i] - 'A' +10; //求出该字母所代表的十进制数
t1 = t1 *n +t; //求出最终转换成的10进制数
}
t=0;
strupr(b);
len=strlen(b);
double t2=0,t3=0;
for(i=len-1; i>=0; i--)
{
if((b[i] - '0' >= n && b[i] < 'A') || b[i] - 'A' + 10 >n ) //判断输入的数据和进制数是否符合
{
printf("data error!!\n"); //错误
exit (0);
}
if(b[i] >='0' && b[i] <= '9') //判断是否为数字
t = b[i] - '0'; //求出该数字赋值给t
else if (n >=11 && (b[i] >= 'A' && b[i] <= 'A' +n -10)) //判断是否为字母
t = b[i] - 'A' +10;
t2=t2/n+(double)t/n;
}
t3=t1+t2;
return t3;
}
}