C C++最全C语言实现简单计算器,推荐一个GitHub项目

img
img

网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

需要这份系统化的资料的朋友,可以添加戳这里获取

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

		if ((ceil(a) == (int)a) && (floor(a) == (int)a))
			sprintf(A, "%d", (int)a);
		else sprintf(A, "%f", a);
		if ((ceil(b) == (int)b) && (floor(b) == (int)b))
			sprintf(B, "%d", (int)b);
		else sprintf(B, "%f", b);
		if ((ceil(Ans) == (int)Ans) && (floor(Ans) == (int)Ans))
			sprintf(ANS, "%d", (int)Ans);
		else sprintf(ANS, "%f", Ans);
		//将a、b、Ans从float型数据转为字符串并分别存储与A、B、ANS中

		strcpy(HistoryOperate[0], "");//清空
		strcat(HistoryOperate[0], "\033[32m");
		strcat(HistoryOperate[0], A);
		strcat(HistoryOperate[0], "*");
		strcat(HistoryOperate[0], B);
		strcat(HistoryOperate[0], "=");
		strcat(HistoryOperate[0], ANS);
		strcat(HistoryOperate[0], "\033[0m");
		//连接字符串函数,用于存储最新的记录
		//分多句连接避免"strcat实参过多"警告
		//存储记录时就把颜色存进去,增强页面美化的兼容性
		Operate[0] = Oper;//操作序号也作记录,便于输出历史记录时查找当时操作

		printf_s("\033[35m>\033[32mThe answer is :\033[0m%s\n", ANS);
		printf_s("\n\033[35m*\033[32mThe operate has been saved temporarily.\n\033[35m*\033[32mIf you exit the software,the memory will lost.\033[0m");
		break;

	case 4://当选择1操作时应当为除法操作
	DividedByZero://如果输入分母为0,则重新询问数据

		printf_s("\n\033[35m*\033[32mPlease input the two numbers you want to divide:\033[0m");
		//提示用户输入两个需要相除的数字
		scanf_s("%f", &a);
		scanf_s("%f", &b);//读取两个float浮点数

		if (b != 0)//分母不能为0
		{
			Ans = a / b;

			for (i = 3; i >= 0; i--)//用原来的0-3总计四条记录覆盖掉1-4的记录,实现记录的后移,为新记录腾出空间
			{
				strcpy(HistoryOperate[i + 1], HistoryOperate[i]);
				Operate[i + 1] = Operate[i];
			}

			if ((ceil(a) == (int)a) && (floor(a) == (int)a))
				sprintf(A, "%d", (int)a);
			else sprintf(A, "%f", a);
			if ((ceil(b) == (int)b) && (floor(b) == (int)b))
				sprintf(B, "%d", (int)b);
			else sprintf(B, "%f", b);
			if ((ceil(Ans) == (int)Ans) && (floor(Ans) == (int)Ans))
				sprintf(ANS, "%d", (int)Ans);
			else sprintf(ANS, "%f", Ans);
			//将a、b、Ans从float型数据转为字符串并分别存储与A、B、ANS中

			strcpy(HistoryOperate[0], "");//清空
			strcat(HistoryOperate[0], "\033[32m");
			strcat(HistoryOperate[0], A);
			strcat(HistoryOperate[0], "/");
			strcat(HistoryOperate[0], B);
			strcat(HistoryOperate[0], "=");
			strcat(HistoryOperate[0], ANS);
			strcat(HistoryOperate[0], "\033[0m");
			//连接字符串函数,用于存储最新的记录
			//分多句连接避免"strcat实参过多"警告
			//存储记录时就把颜色存进去,增强页面美化的兼容性
			Operate[0] = Oper;//操作序号也作记录,便于输出历史记录时查找当时操作

			printf_s("\033[35m>\033[32mThe answer is :\033[0m%s\n", ANS);
			printf_s("\n\033[35m*\033[32mThe operate has been saved temporarily.\n\033[35m*\033[32mIf you exit the software,the memory will lost.\033[0m");
		}
		else //如果为0,那么提示用户数据错误并要求重新输入
		{
			printf_s("\033[35m>\033[31mThe digit can't divided by \033[33mZERO \033[31m!\n");
			printf_s("\033[35m>\033[31mPlease check your data and try it again!\n\033[0m");
			goto DividedByZero;//跳回开头,重新询问数据
		}
		break;


	case 5://当选择1操作时应当为整除操作
	intDivideNotAllowed://如果输入的数据含有小数,则跳回重新询问数据

		printf_s("\n\033[35m*\033[32mPlease input the two numbers you want to int-divide:\033[0m");
		//提示用户输入两个需要相乘的数字
		int a_1, b_1, Ans_1;//用于储存该case的专用数据,分别对应a、b、Ans的整数形式

		scanf_s("%f", &a);
		scanf_s("%f", &b);//读取两个float浮点数
		_Bool aIsInt = 0, bIsInt = 0;//用于记录a、b是否是整数的_Bool变量

		if ((ceil(a) == (int)a) && (floor(a) == (int)a))//判断输入的a是否是整数
		{
			a_1 = (int)a;
			aIsInt = 1;
		}
		if ((ceil(b) == (int)b) && (floor(b) == (int)b))//判断输入的b是否是整数
		{
			b_1 = (int)b;
			bIsInt = 1;
		}

		if (aIsInt && bIsInt)//如果两个都是整数,那么执行计算操作
		{
			Ans_1 = a_1 / b_1;

			for (i = 3; i >= 0; i--)//用原来的0-3总计四条记录覆盖掉1-4的记录,实现记录的后移,为新记录腾出空间
			{
				strcpy(HistoryOperate[i + 1], HistoryOperate[i]);
				Operate[i + 1] = Operate[i];
			}

			sprintf(A, "%d", a_1);
			sprintf(B, "%d", b_1);
			sprintf(ANS, "%d", Ans_1);
			//将a、b、Ans从float型数据转为字符串并分别存储与A、B、ANS中

			strcpy(HistoryOperate[0], "");//清空
			strcat(HistoryOperate[0], "\033[32m");
			strcat(HistoryOperate[0], A);
			strcat(HistoryOperate[0], "/");
			strcat(HistoryOperate[0], B);
			strcat(HistoryOperate[0], "=");
			strcat(HistoryOperate[0], ANS);
			strcat(HistoryOperate[0], "\t\033[33m(int-divide)\033[0m");
			//连接字符串函数,用于存储最新的记录
			//分多句连接避免"strcat实参过多"警告
			//存储记录时就把颜色存进去,增强页面美化的兼容性
			Operate[0] = Oper;//操作序号也作记录,便于输出历史记录时查找当时操作

			printf_s("\033[35m>\033[32mThe answer is :\033[0m%s\n", ANS);
			printf_s("\n\033[35m*\033[32mThe operate has been saved temporarily.\n\033[35m*\033[32mIf you exit the software,the memory will lost.\033[0m");
		}
		else //否则告知用户数据错误并跳回继续询问数据
		{
			printf_s("\033[35m>\033[31mThe digit should be integer!\n");
			printf_s("\033[35m>\033[31mPlease check your data and try it again!\n\033[0m");
			goto intDivideNotAllowed;//跳回该case的开头重新询问数据并继续判断
		}
		break;


	case 6://当选择1操作时应当为取余操作
	ModDividedByZero://如果输入分母为0,则重新询问数据

		printf_s("\n\033[35m*\033[32mPlease input the two numbers you want to Mod-divide:\033[0m");
		//提示用户输入两个需要相除的数字
		scanf_s("%f", &a);
		scanf_s("%f", &b);//读取两个float浮点数

		int a_2, b_2, Ans_2; //用于储存该case的专用数据,分别对应a、b、Ans的整数形式
		_Bool aIsInt_2 = 0, bIsInt_2 = 0;//用于记录a、b是否是整数的_Bool变量

		if ((ceil(a) == (int)a) && (floor(a) == (int)a))//判断输入的a是否是整数
		{
			a_2 = (int)a;
			aIsInt_2 = 1;
		}
		if ((ceil(b) == (int)b) && (floor(b) == (int)b))//判断输入的b是否是整数
		{
			b_2 = (int)b;
			bIsInt_2 = 1;
		}

		if ((b != 0) && aIsInt_2 && bIsInt_2)//分母不能为0且分子分母必须为整数
		{
			Ans_2 = a_2 % b_2;//计算取余

			for (i = 3; i >= 0; i--)//用原来的0-3总计四条记录覆盖掉1-4的记录,实现记录的后移,为新记录腾出空间
			{
				strcpy(HistoryOperate[i + 1], HistoryOperate[i]);
				Operate[i + 1] = Operate[i];
			}

			sprintf(A, "%d", a_2);
			sprintf(B, "%d", b_2);
			sprintf(ANS, "%d", Ans_2);
			//将a、b、Ans从float型数据转为字符串并分别存储与A、B、ANS中

			strcpy(HistoryOperate[0], "");//清空
			strcat(HistoryOperate[0], "\033[32m");
			strcat(HistoryOperate[0], A);
			strcat(HistoryOperate[0], "/");
			strcat(HistoryOperate[0], B);
			strcat(HistoryOperate[0], "=");
			strcat(HistoryOperate[0], ANS);
			strcat(HistoryOperate[0], "\033[0m");
			//连接字符串函数,用于存储最新的记录
			//分多句连接避免"strcat实参过多"警告
			//存储记录时就把颜色存进去,增强页面美化的兼容性
			Operate[0] = Oper;//操作序号也作记录,便于输出历史记录时查找当时操作

			printf_s("\033[35m>\033[32mThe answer is :\033[0m%s\n", ANS);
			printf_s("\n\033[35m*\033[32mThe operate has been saved temporarily.\n\033[35m*\033[32mIf you exit the software,the memory will lost.\033[0m");
		}
		else //如果为0,那么提示用户数据错误并要求重新输入
		{
			if (b == 0)
				printf_s("\033[35m>\033[31mThe digit can't divided by \033[33mZERO \033[31m!\n");
			else printf_s("\033[35m>\033[31mThe digit should be integer!\n");
			printf_s("\033[35m>\033[31mPlease check your data and try it again!\n\033[0m");
			goto ModDividedByZero;//跳回开头,重新询问数据
		}
		break;


	case 7://当选择1操作时应当为查看历史记录操作
		printf_s("\033[35m>\033[32mThe history operates are as follows:\033[0m\n");
		printf_s("\033[33mNEW \n\033[0m");
		for (j = 0; j < 5; j++)
		{
			switch (Operate[j])
			{
			case 9://操作为9时按照排序格式输出记录

				break;

			default://当操作为1-6时正常输出记录
				printf_s("\033[33m | \t\033[35m%d.\033[0m%s\n", j + 1, HistoryOperate[j]);
				break;
			}
		}
		printf_s("\033[33mOLD \n\033[0m");

		break;


	case 8://当选择1操作时应当为退出操作
		printf_s("\n");
	WrongInputToBack://退出操作输入错误则继续询问

		printf_s("\033[31mATTENTION:THE HISTORY OPERATE MEMORY WILL LOST!\n\033[0m");
		printf_s("\033[35mDo you want to exit the calculater?(Y/N)\033[0m");//询问用户是否退出

		char ExitOrNot;
		do {//读取非回车与空格的第一个字符
			scanf_s("%c", &ExitOrNot);
		} while ((ExitOrNot == '\n') || (ExitOrNot == ' '));

		switch (ExitOrNot)//判断用户的输入是Y还是N还是不符合要求
		{
		case 'Y'://输入Y则退出软件
			printf_s("\033[35m>\033[36mThanks to your use!\n");
			printf_s("\033[35m>\033[36mExiting……\n\033[0m");
			_sleep(1500);//单位是ms
			printf_s("\033[35m>\033[36mExited……\n\033[0m");
			_exit(0);//就是图个好看
			return 0;

		case 'N'://输入N则软件继续运行
			printf_s("\033[35m>\033[33mThe calculater continue running……\n\033[0m");
			break;

		default://不符合输入条件则提示用户并要求重新输入
			printf_s("\033[35m>\033[31mWrong Input!\033[0m\n");
			goto WrongInputToBack;
		}


	case 9://当选择1操作时应当为排序操作
		printf_s("\033[35m>\033[32mIn order to sort the digit,I need know how many digits there are.\n");
		printf_s("\033[35m*\033[32mPlease input the number of digit:\033[0m");//提示用户输入需要排序的数据的个数
		int n;
		scanf_s("%d", &n);//读取数字个数

		for (i = 3; i >= 0; i--)//用原来的0-3总计四条记录覆盖掉1-4的记录,实现记录的后移,为新记录腾出空间
		{
			strcpy(HistoryOperate[i + 1], HistoryOperate[i]);
			Operate[i + 1] = Operate[i];
		}

		printf_s("\033[35m>\033[32mNow please input the digits:\033[0m");//提示用户输入数据
		strcpy(HistoryOperate[0], "\033[32mSORT:\n\033[33m | \t");//先初始化,即清空
		strcat(HistoryOperate[0], "\033[32mThe \033[33mRAW \033[32mdata:\n\033[33m ┝ \033[32m\t\t");//排版
		char Temp[8];//用于临时储存数据的字符串

		for (i = 0; i <= n - 1; i++)
		{
			scanf_s("%f", &Num[i]);//读取用户输入的数据
			sprintf(Temp, "%f", Num[i]);//将Num[i]转化为字符串并储存在临时字符串Temp中
			strcat(HistoryOperate[0], Temp);
			strcat(HistoryOperate[0], " ");
		}

		strcat(HistoryOperate[0], "\n\033[33m | \t\033[32mThe \033[33mNEW \033[32mdata:\n\033[33m ┝ \033[32m\t\t");//排版

		float max;//选择排序
		int Location;//未排序序列最大值的位置
		for (i = 0; i < n - 1; i++)
		{
			max = Num[i];
			Location = i;//将未排序序列的第一项赋值为max,保证数据在未排序序列范围内
			for (j = i + 1; j <= n - 1; j++)
				if (Num[j] > max)
				{
					max = Num[j];
					Location = j;
				}
			if (Location != i) swap(&Num[i], &Num[Location]);
		}//到这里选择排序就排好了

	WrongInputToBack_2://输入错误则跳回这里来
		printf_s("\033[35m>\033[32mplease choose up-order or down-order:(U/D)\033[0m");
		char UpOrDown;
		do {
			scanf_s("%c", &UpOrDown);
		} while ((UpOrDown == '\n') || (UpOrDown == ' '));

		switch (UpOrDown)//判断用户的输入是Y还是N还是不符合要求
		{
		case 'U'://输入U则升序
			for (i = n - 1; i >= 0; i--)//储存排序好的顺序
			{
				sprintf(Temp, "%f", Num[i]);//将Num[i]转化为字符串并储存在临时字符串Temp中
				printf_s("\033[32m");
				printf_s(Temp);
				printf_s(" ");//避免"printf_s()实参过多"警告
				strcat(HistoryOperate[0], Temp);
				strcat(HistoryOperate[0], " ");
			}
			printf_s("\n");
			break;

		case 'D'://输入D则降序
			for (i = 0; i <= n - 1; i++)//储存排序好的顺序
			{
				sprintf(Temp, "%f", Num[i]);//将Num[i]转化为字符串并储存在临时字符串Temp中
				printf_s("\033[32m");
				printf_s(Temp);
				printf_s(" ");//避免"printf_s()实参过多"警告
				strcat(HistoryOperate[0], Temp);
				strcat(HistoryOperate[0], " ");
			}
			printf_s("\n");
			break;

		default://不符合输入条件则提示用户并要求重新输入
			printf_s("\033[35m>\033[31mWrong Input!\033[0m\n");
			goto WrongInputToBack_2;
		}

		break;
	}
} while (1);//保证计算器持续运行
return 0;

}

void swap(float* a, float*b)
{//实现交换数值的函数
float c = *a;
*a = *b;
*b = c;
}

void OutputThePanel(void)
{
printf_s(“\n”);
printf_s(“\033[32m __________________________________________ \n”);
printf_s(“\033[32m/########\033[0mPlease Choose Your Operate\033[32m########\ \n”);
printf_s(“\033[32m|##########################################| \n”);
printf_s(“\033[32m|##\033[0m 1.\033[32mAdd(+) \033[0m2.\033[32mSub(-) ##| \n”);
printf_s(“\033[32m|##\033[0m 3.\033[32mMulti(*) \033[0m4.\033[32mDiv(/) ##| \n”);
printf_s(“\033[32m|##\033[0m 5.\033[32mInt_Div(/) \033[0m6.\033[32mMod_Div(%%) ##| \n”);
printf_s(“\033[32m|##\033[0m 7.\033[32mHistory Operate Checker(5 steps) \033[32m##| \n”);
printf_s(“\033[32m|##\033[0m 8.\033[32mExit Calculater(History Will Lost)\033[32m##| \n”);
printf_s(“\033[32m┝------------------------------------------┥ \n”);
printf_s(“\033[32m|## \033[33mPLUS FEATURES: \033[32m##| \n”);
printf_s(“\033[32m|##\033[0m 9.\033[32mSort Data(NO MORE THAN 50) ##| \n”);
printf_s(“\033[32m|## You can choose operate from 1 to 9. ##| \n”);
printf_s(“\033[32m\##########################################/ \n”);
printf_s(“\033[32m ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ \n”);
}


内部头文件unistd.h借鉴了如下内容:



/** This file is part of the Mingw32 package.

  • unistd.h maps (roughly) to io.h
    */

#ifndef _UNISTD_H
#define _UNISTD_H
#include <io.h>
#include <process.h>
#endif /* _UNISTD_H */


## 接下来几段代码细讲:


### 颜色设置:



printf_s(“\033[0mA \033[31mB \033[32mC \033[33mD \033[34mE \033[35mF \033[36mG”);


运行结果: 


![](https://img-blog.csdnimg.cn/3cdaee792b4648e49316bc6402bc64a4.jpeg)


### 历史操作记录的保存:


主要代码: 



char HistoryOperate[5][1250] = { "EMPTY", "EMPTY", "EMPTY", "EMPTY", "EMPTY" };//用于存储五步历史步骤,0表示最新的记录

img
img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上C C++开发知识点,真正体系化!

由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、讲解视频,并且后续会持续更新

如果你需要这些资料,可以戳这里获取

史操作记录的保存:

主要代码:


	char HistoryOperate[5][1250] = { "EMPTY", "EMPTY", "EMPTY", "EMPTY", "EMPTY" };//用于存储五步历史步骤,0表示最新的记录




[外链图片转存中...(img-KIsoTnUY-1715691870199)]
[外链图片转存中...(img-R9N0f6Fj-1715691870199)]

**既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上C C++开发知识点,真正体系化!**

**由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、讲解视频,并且后续会持续更新**

**[如果你需要这些资料,可以戳这里获取](https://bbs.csdn.net/topics/618668825)**

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值