简介:
需求:用栈的结构实现四种进制转换,包括整数、浮点数、负数
思路:
先构造栈,包括有栈的结构函数、初始化函数、输入输出函数等,可以写在stack.h调用,
但我这里用栈还是用来忽悠完成实训的,
实际上代码中用到栈的部分可以用数组实训
输入数据一律视为字符串,分为整数部分、小数点、小数部分,
其中设立一个flag判断是否是浮点数以及小数点在哪个位置,
若是浮点数,确定小数点的位置,将整数与小数分开,
分别对小数点左边(整数部分)、右边(浮点数部分)做运算,
但是最后输出的时候要“拼”起来
四种进制之间的转换统一为:十进制→其他进制,其他进制→十进制,用两个函数实现
主函数负责输入数据、调用其他函数、输出结果
PS:关于十进制整数、小数如何转换成其他进制的具体思路,
或者其他进制整数、小数如何转换成十进制的具体思路,
请自行百度,百度上非常详细。。。。。。。
步骤:
太长了,懒得写了,详细见代码/笑哭/笑哭(小白的代码还是很好理解的。。。)
可能出现的问题:
运行环境:visual studio 2019
解决办法:
添加一句命令:_CRT_SECURE_NO_WARNINGS
运行预览:
代码如下:
/*********************
小白一枚,参考了网上的一些大神的思路,
同时也有舍友的帮助,但是主要还是自写的,若有更好的想法,可以讨论研究研究
*********************/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include <malloc.h>
/*----------全局变量----------*/
#define True 1
#define False 0
#define N 100
typedef char datatype;
/*------------------------------栈------------------------------*/
//栈的结构
typedef struct node
{
datatype data[N];
int top;
}Stack;
//初始化,构建空栈
void InitStack(Stack* S)
{
S->top = -1;
}
//入栈
void Push(Stack* S, datatype e)
{
S->top++;
S->data[S->top] = e;
}
//出栈
void Pop(Stack* S)
{
if (S->top == -1)
printf("\nstack is full.\n");
else
S->top--;
}
//打印栈
void showStack(Stack* S)
{
if (S->top == -1)
printf("\nstack is full.\n");
else
{
for (int i = S->top; i >= 0; i--)
printf("%c", S->data[i]);
}
printf("\n");
}
/*------------------------------十进制转其他进制------------------------------*/
//S是栈,num是字符数组,mode是十进制要转换的类型
void DecToOther(Stack* S, char* num, int mode)
{
//定义整数部分和小数部分
int leftnum;
double rightnum = 0;
//记录小数点的位置
int pos;//位置
int flag = 0;//旗标
for (int i = 0; num[i] != '\0'; i++)
{
if (num[i] == '.')
{
pos = i;
flag = 1;
break;
}
else
pos = i;//没有小数的时候,即输入的是整数
}
/*----------左边整数部分(此处用到栈)----------*/
//1、将字符数组转为一个整数进行运算
for (int j = 0; j < pos; j++)
leftnum = atoi(num);
// printf("left=%d",leftnum);
//2、定义两个中间变量分别保留整数、压栈时的字符
int ternum;
char terchs;
//3、有可能有符号,定义一个符号变量保存符号
char cala = NULL;
//4、压栈转制
//大于0
if (leftnum > 0)
{
do
{
ternum = leftnum % mode;
if (ternum > 9)
terchs = ternum - 10 + 'A';
else
terchs = ternum + '0';
Push(S, terchs);
leftnum = leftnum / mode;
} while (leftnum != 0);
}
//小于0
else if (leftnum < 0)
{
cala = '-';//保存负号
leftnum = leftnum * (-1);//化为正数
do
{
ternum = leftnum % mode;
if (ternum > 9)
terchs = ternum - 10 + 'A';
else
terchs = ternum + '0';
Push(S, terchs);
leftnum = leftnum / mode;
} while (leftnum != 0);
}
//等于0
else
{
Push(S, '0');
}
/*----------右边小数部分----------*/
//1、字符数组转整数
int mi = 1;//幂
for (int x = pos + 1; num[x] != '\0'; x++)
rightnum += (num[x] - '0') * pow(10, -mi++);
//2、转换
//保存每次取整的数
int intnum = 1;
int count = 0;
//保存结果
int acc[40];
//保留后6位
for (int k = 0; k < 6; k++)
{
if (intnum >= 0 && intnum < mode)
{
//取整
intnum = rightnum * mode;
//取出小数部分
rightnum = (rightnum * mode) - intnum;
//保存每次运算后的整数
acc[count++] = intnum;
}
}
//3、输出结果
char bcc[40];//字符
acc[count] = -1;
//重置数组小标,从头遍历
count = 0;
for (int k = 0; acc[k] != -1; k++)
{
if (acc[k] > 9)
bcc[count++] = (acc[k] - 10) + 'A';
else
bcc[count++] = acc[k] + '0';
}
bcc[count] = '\0';
/*----------输出最后结果----------*/
//左边输出为字符串
num[S->top + 1] = '\0';
int d = 0;
//有负号
if (cala != NULL)
{
num[0] = cala;
d = 1;
for (int k = S->top; k >= 0; k--)
{
num[d++] = S->data[k];
}
num[d] = '\0';
//输出
char point[10] = ".";
char* lian2 = strcat(num, point);
num = strcat(lian2, bcc);
}
//无负号
else
{
//有小数点
if (flag == 1)
{
d = 0;
for (int k = S->top; k >= 0; k--)
num[d++] = S->data[k];
//输出
char point[10] = ".";
char* lian2 = strcat(num, point);
num = strcat(lian2, bcc);
}
else
{
d = 0;
for (int k = S->top; k >= 0; k--)
num[d++] = S->data[k];
}
}
}
/*------------------------------其他进制转十进制------------------------------*/
//S是栈,num是字符数组,mode是要转换的类型
void OtherToDec(char* num, int mode)
{
//定义整数部分和小数部分
char leftchs[40];
char rightchs[40];
//小数点的位置和旗标
int flag = 0;
int pos;
for (int i = 0; num[i] != '\0'; i++)
{
if (num[i] == '.')
{
flag = 1;
pos = i;
}
}
/*----------左边整数部分----------*/
//定义一个循环变量
int z;
//没有小数点的情况
if (flag == 0)
{
//提取左边的整数字符串
for (z = 0; num[z] != '\0'; z++)
leftchs[z] = num[z];
}
else
{
for (z = 0; z < pos; z++)
leftchs[z] = num[z];
}
//计算长度
leftchs[z] = '\0';
int leftlen = strlen(leftchs);
//转换
int leftsum = 0;
int mi;//幂
char cala = NULL;//符号,这次是提取字符串里的负号
int k;//用作循环
if (mode == 2 || mode == 8 || mode == 16)
{
//为正
if (leftchs[0] != '-')
{
mi = leftlen - 1;
for (k = 0; k < leftlen; k++)
{
int term;
if (leftchs[k] <= '9')
term = leftchs[k] - '0';
else
term = leftchs[k] - 'A' + 10;
leftsum += (term * (pow(mode, mi)));
mi--;
}
}
//为负
else
{
//负号标志
cala = '-';
mi = leftlen - 2;
//从第二位开始算
for (k = 1; k < leftlen; k++)
{
int term;
if (leftchs[k] <= '9')
term = leftchs[k] - '0';
else
term = leftchs[k] - 'A' + 10;
leftsum += (term * (pow(mode, mi)));
mi--;
}
}
}
else
printf("\n\t\t输入的进制有误!!!\n");
/*----------右边小数部分----------*/
//提取右边小数字符
int f = 0;
if (flag == 1)
{
for (z = pos + 1; num[z] != '\0'; z++)
{
rightchs[f] = num[z];
f++;
}
}
//计算长度
rightchs[f] = '\0';
int rightlen = strlen(rightchs);
//转换
double rightsum = 0;
if (rightchs[0] != '-')
{
if (mode == 2 || mode == 8 || mode == 16)
{
mi = -1;
for (k = 0; k < rightlen; k++)
{
int term;
if (rightchs[k] <= '9')
term = rightchs[k] - '0';
else
term = rightchs[k] - 'A' + 10;
rightsum += (term * (pow(mode, mi)));
mi--;
}
}
else
printf("\n\t\t输入的进制有误!!!\n");
}
else
printf("\n\t\t小数部分不能小于0\n");
/*----------输出最后结果----------*/
//printf("\n\t\t结果是:\n");
double zong;
if (cala == NULL)
{
zong = leftsum + rightsum;
sprintf(num, "%f", zong);
}
else
{
zong = leftsum + rightsum;
zong = zong * (-1);
sprintf(num, "%f", zong);
}
}
//主函数
int main(void)
{
printf(" \n");
printf(" \n");
printf("\t☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆\n");
printf("\t☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆\n");
printf("\t☆☆ ☆☆\n");
printf("\t☆☆ 欢迎使用进制转换器!!! ☆☆\n");
printf("\t☆☆ ☆☆\n");
printf("\t☆☆ ★★★支持正负整数和小数★★★ ☆☆\n");
printf("\t☆☆ ☆☆\n");
printf("\t☆☆ 1、二—>八 2、二—>十 3、二—>十六 ☆☆\n");
printf("\t☆☆ ☆☆\n");
printf("\t☆☆ 4、八—>二 5、八—>十 6、八—>十六 ☆☆\n");
printf("\t☆☆ ☆☆\n");
printf("\t☆☆ 7、十—>二 8、十—>八 9、十—>十六 ☆☆\n");
printf("\t☆☆ ☆☆\n");
printf("\t☆☆ 10、十六—>二 11、十六—>八 12、十六—>十 ☆☆\n");
printf("\t☆☆ ☆☆\n");
printf("\t☆☆ 0、退出 ☆☆\n");
printf("\t☆☆ ☆☆\n");
printf("\t☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆\n");
printf("\t☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆\n");
do {
printf("\n\t\t请选择相应的数字进行相应的操作:");
int choicenum;
scanf("%d", &choicenum);
//用户输入的数值
char num[100];
char pan;
//定义栈
Stack s;
InitStack(&s);
if (choicenum >= 0 && choicenum <= 13)
{
if (choicenum == 0)
exit(0);
/*****************************************二进制******************************************/
//二—>八
else if (choicenum == 1)
{
ou1:
printf("\n\t\t请输入一个二进制数:");
scanf("%s", num);
int flag = 1;
for (int i = 0; i < strlen(num); i++)
{
if (num[i] > '1')
{
flag = 0;
break;
}
}
if (flag == 1)
{
OtherToDec(num, 2);
DecToOther(&s, num, 8);
printf("\n\t\t结果是=%s", num);
printf("\n\t\t--------------------------------------------------\n");
//system("cls");
}
else
goto ou1;
}
//二—>十
else if (choicenum == 2)
{
ou2:
printf("\n\t\t请输入一个二进制数:");
scanf("%s", num);
int flag = 1;
for (int i = 0; i < strlen(num); i++)
{
if (num[i] > '1')
{
flag = 0;
break;
}
}
if (flag == 1)
{
OtherToDec(num, 2);
printf("\n\t\t结果是=%s", num);
printf("\n\t\t--------------------------------------------------\n");
}
else
goto ou2;
}
//二—>十六
else if (choicenum == 3)
{
ou3:
printf("\n\t\t请输入一个二进制数:");
scanf("%s", num);
int flag = 1;
for (int i = 0; i < strlen(num); i++)
{
if (num[i] > '1')
{
flag = 0;
break;
}
}
if (flag == 1)
{
OtherToDec(num, 2);
DecToOther(&s, num, 16);
printf("\n\t\t结果是=%s", num);
printf("\n\t\t--------------------------------------------------\n");
}
else
goto ou3;
}
/*****************************************八进制******************************************/
//八—>二
else if (choicenum == 4)
{
ou4:
printf("\n\t\t请输入一个八进制数:");
scanf("%s", num);
int flag = 1;
for (int i = 0; i < strlen(num); i++)
{
if (num[i] > '8')
{
flag = 0;
break;
}
}
if (flag == 1)
{
OtherToDec(num, 8);
DecToOther(&s, num, 2);
printf("\n\t\t结果是=%s", num);
printf("\n\t\t--------------------------------------------------\n");
}
else
goto ou4;
}
//八—>十
else if (choicenum == 5)
{
ou5:
printf("\n\t\t请输入一个八进制数:");
scanf("%s", num);
int flag = 1;
for (int i = 0; i < strlen(num); i++)
{
if (num[i] > '8')
{
flag = 0;
break;
}
}
if (flag == 1)
{
OtherToDec(num, 8);
printf("\n\t\t结果是=%s", num);
printf("\n\t\t--------------------------------------------------\n");
}
else
goto ou5;
}
//八—>十六
else if (choicenum == 6)
{
ou6:
printf("\n\t\t请输入一个八进制数:");
scanf("%s", num);
int flag = 1;
for (int i = 0; i < strlen(num); i++)
{
if (num[i] > '8')
{
flag = 0;
break;
}
}
if (flag == 1)
{
OtherToDec(num, 8);
DecToOther(&s, num, 16);
printf("\n\t\t结果是=%s", num);
printf("\n\t\t--------------------------------------------------\n");
}
else
goto ou6;
}
/*****************************************十进制******************************************/
//十—>二
else if (choicenum == 7)
{
printf("\n\t\t请输入一个十进制数:");
scanf("%s", num);
DecToOther(&s, num, 2);
printf("\n\t\t结果是=%s", num);
printf("\n\t\t--------------------------------------------------\n");
}
//十—>八
else if (choicenum == 8)
{
printf("\n\t\t请输入一个十进制数:");
scanf("%s", num);
DecToOther(&s, num, 8);
printf("\n\t\t结果是=%s", num);
printf("\n\t\t--------------------------------------------------\n");
}
//十—>十六
else if (choicenum == 9)
{
printf("\n\t\t请输入一个十进制数:");
scanf("%s", num);
DecToOther(&s, num, 16);
printf("\n\t\t结果是=%s", num);
printf("\n\t\t--------------------------------------------------\n");
}
/*****************************************十六进制******************************************/
//十六—>二
else if (choicenum == 10)
{
printf("\n\t\t请输入一个十六进制数:");
scanf("%s", num);
OtherToDec(num, 16);
DecToOther(&s, num, 2);
printf("\n\t\t结果是=%s", num);
printf("\n\t\t--------------------------------------------------\n");
}
//十六—>八
else if (choicenum == 11)
{
printf("\n\t\t请输入一个十六进制数:");
scanf("%s", num);
OtherToDec(num, 16);
DecToOther(&s, num, 8);
printf("\n\t\t结果是=%s", num);
printf("\n\t\t--------------------------------------------------\n");
}
//十六—>十
else if (choicenum == 12)
{
printf("\n\t\t请输入一个十六进制数:");
scanf("%s", num);
OtherToDec(num, 16);
printf("\n\t\t结果是=%s", num);
printf("\n\t\t--------------------------------------------------\n");
}
}
} while (1);
return 0;
}