C语言—用栈实现四种基本进制之间的正负小数转换

 简介:

 需求:用栈的结构实现四种进制转换,包括整数、浮点数、负数

 思路:
       先构造栈,包括有栈的结构函数、初始化函数、输入输出函数等,可以写在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;
}

 

  • 1
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值