[c++] 一个支持安装卸载,复杂运算的简易计算器

Posted 泥烟

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[c++] 一个支持安装卸载,复杂运算的简易计算器相关的知识,希望对你有一定的参考价值。

这是大一放假前最后做的一个小玩意,现在抽空整理了一下,纪念自己第一个作品

目录

一.技术栈,开发工具

二.需求分析

三.核心算法

四.成果展示

五. 遇到的问题

没加标准表达式

打包过程中的问题

添加卸载的功能

七.安装包获取以及代码

 Calculator.h

Calculator.cpp

main.cpp



一.技术栈,开发工具

c++基本语法,STL中队列和栈的应用,以及用vs打包的相关操作

开发工具:vs2019 和部分插件

二.需求分析

支持+(加)-(减)*(乘)/(除)^(幂次)等混合运算,在输入时配有其他辅助符号:(),[ ],{ }。输入时必须按照数学标准正确输入。

三.核心算法

逆波兰式的应用

四.成果展示

如果缺少vs环境,会出现错误,因此我将项目改为了静态链接,会提供静态库,相应的.dll文件会加入.msi文件中,无须自己添加

 点击TT计算器2.0.msi(如果已有vs环境,用setup应该也是可以的)

选择安装目录

 安装完成

 此时桌面就出现了快捷方式

由于链接库,第一次运行可能会慢一点

 

 

安装目录下会有提供的文件:

unstall.exe   ----卸载

 

log.txt   -----日志

五. 遇到的问题

QAQ真是不少....

没加标准表达式

表达式负号与减号混淆,结果会出问题

打包过程中的问题

由于找不到VCRUNTIME140D.dIl,无法继续执行代码。

重新安装程序可能会解决此问题。

为什么会这样呢?原因是VS默认为动态编译。在之前的教程里我们学了静态编译与动态编译的区别,我再把他搬过来:静态编译在程序编译时dll会被连接到目标代码中,程序运行时将不再需要该静态库。动态编译在程序编译时dll并不会被连接到目标代码中,而是在程序运行是才被载入,因此在程序运行时还需要动态库存在。我们只需设置为静态编译即可,让dll写进exe内,没有外部库也可以运行。

 然后重新编译即可。对于VS来说:静态编译/MT,/MTD 是指使用libc和msvc相关的静态库(lib)。动态编译,/MD,/MDd是指用相应的DLL版本编译。值得注意的是,使用静态编译会让程序变大。

添加卸载的功能

 没有安装卸载程序的话,需要在控制面板\\所有控制面板项\\程序和功能下卸载比较麻烦。

所以,
在C盘下搜索系统卸载程序,选择64位,复制到我们工程的Release目录下。

 选择msiexec.exe文件,并创建快捷方式

并将其重命名然后移到User's Desktop


点击setup项目,将其属性中的产品码ProductCode后的内容复制下来如:{E9A43663-33ED-4EF6-AB62-E8487863D2FF}


粘贴到untall.exe的Arguments中,并在前面加上"/x ",如/x {E9A43663-33ED-4EF6-AB62-E8487863D2FF},/x和{间有空格!

七.安装包获取以及代码

https://wws.lanzoui.com/iETMPq95i2f

 Calculator.h


/*
			@author : Knight02
			Created on Tue June 1 22:56:45 2021
*/

#include <stack>
#include <vector>
#include <string>
using namespace std;


class Calculator
{
private:
	stack<char> symbolStack;				//符号栈
	stack<double> digitStack;				//数字栈

	string standard_Expression;			//★★标准表达式★★
	vector<string> postfix_Expression;	//★★(向量)后缀表达式★★

	double result;						//最终计算结果
	bool error;							//除数异常
public:
	string systemExplanation;			//系统说明
	string expressionBuffer;			//计算表达式缓存区
	
	Calculator();
	void getFormat();					//标准表达式转化
	void getPostfix();					//后缀表达式转换
	
	void calResult();					//计算后缀表达式
	void OperationalProcess();			//操作过程

	int getPriority(char c);			//获取算术符号优先级
	void initializeResult();			//结果初始化
};

Calculator.cpp

#include <iostream>
#include "Calculator.h"
#include <stack>
#include <vector>
#include <string>
#include <cmath>
using namespace std;

//算术符号优先级
enum SYMBOL_PRIORITY {
	LV1 = 1,
	LV2 = 2,
	LV3 = 3,
	LV4 = 4,
};

Calculator::Calculator() {	
	systemExplanation = "          TT计算器2.0\\n支持 +(加) -(减) *(乘)  /(除) ^(幂次)等混合运算\\n其他辅助符号:( ) [ ] { }\\n请务必按照数学标准形式输入,\\n因算式不标准产生歧意而结果不实,本系统概不负责!";
	result = 0.0;
}


//标准表达式转化
void Calculator::getFormat() {

	standard_Expression = expressionBuffer;

	//正负处理(与加减区分开)!
	for (string::size_type i = 0; i < standard_Expression.size(); i++) {					//string.size()返回size_type类型,避免下标运算时的类型溢出
		if (standard_Expression[i] == '-' || standard_Expression[i] == '+') {				//-x转换为0-x,+x转化为0+x
			//在表示正负号前插入"0"可以转化为正常的两个数之间的运算
			if (i == 0)
			{
				standard_Expression.insert(0, 1, '0');
			}
			else if (standard_Expression[i - 1] == '(')
			{
				standard_Expression.insert(i, 1, '0');
			}
		}
	}
}

//获取算术符号优先级
int Calculator::getPriority(char c) {

	if (c == '+' || c == '-') {
		return LV2;
	}
	else if (c == '*' || c == '/') {
		return LV3;
	}
	else if (c == '^') {
		return LV4;
	}
	else {
		return LV1;
	}
}

//后缀表达式转换
void Calculator::getPostfix() {
	
	string tmp;
	for (string::size_type i = 0; i < standard_Expression.size(); i++) 
	{					
		tmp = "";
		switch (standard_Expression[i]) {
		case '+':
		case '-':
		case '*':
		case '/':
		case '^':
			if (symbolStack.empty() || symbolStack.top() == '(' || symbolStack.top() == '[' || symbolStack.top() == '{' ) {
				symbolStack.push(standard_Expression[i]);
			}
			else {
				while (!symbolStack.empty() && (getPriority(symbolStack.top()) >= getPriority(standard_Expression[i]))) 
				{
					tmp += symbolStack.top();
					symbolStack.pop();
					postfix_Expression.push_back(tmp);
					tmp = "";
				}
				symbolStack.push(standard_Expression[i]);
			}
			break;
			/************** ***************/
		case '(':
		case '[':
		case '{':
			symbolStack.push(standard_Expression[i]);
			break;
		case ')':
			while (!symbolStack.empty() && symbolStack.top() != '(') 
			{
				tmp += symbolStack.top();
				postfix_Expression.push_back(tmp);
				symbolStack.pop();
				tmp = "";
			}
			if (!symbolStack.empty() && symbolStack.top() == '(') {
				symbolStack.pop();							//  "(" 出栈
			}
			break;
		case ']':
			while (!symbolStack.empty() && symbolStack.top() != '[') 
			{
				tmp += symbolStack.top();
				postfix_Expression.push_back(tmp);
				symbolStack.pop();
				tmp = "";
			}
			if (!symbolStack.empty() && symbolStack.top() == '[') {
				symbolStack.pop();							//  "[" 出栈
			}
			break;
		case '}':
			while (!symbolStack.empty() && symbolStack.top() != '{') 
			{
				tmp += symbolStack.top();
				postfix_Expression.push_back(tmp);
				symbolStack.pop();
				tmp = "";
			}
			if (!symbolStack.empty() && symbolStack.top() == '{') {
				symbolStack.pop();							//   "{"出栈
			}
			break;
		default:
			if ((standard_Expression[i] >= '0' && standard_Expression[i] <= '9')) 
			{
				tmp += standard_Expression[i];
				while (i + 1 < standard_Expression.length() && (standard_Expression[i + 1] >= '0' && standard_Expression[i + 1] <= '9' || standard_Expression[i + 1] == '.')) 
				{	
					tmp += standard_Expression[i + 1];			//多个数字
					i++;
				}
				if (tmp[tmp.length() - 1] == '.') {
					tmp += '0';		
				}
				postfix_Expression.push_back(tmp);
			}
			break;
		}
	}

	//将栈中的剩余符号压入后缀表达式
	while (!symbolStack.empty()) 
	{
		tmp = "";
		tmp += symbolStack.top();
		postfix_Expression.push_back(tmp);
		symbolStack.pop();
	}
}

//计算后缀表达式
void Calculator::calResult() {

	string tmp;
	double number = 0;
	double op1 = 0, op2 = 0;		//运算双方

	for (string::size_type i = 0; i < postfix_Expression.size(); i++) 
	{
		tmp = postfix_Expression[i];
		if (tmp[0] >= '0' && tmp[0] <= '9') {
			number = atof(tmp.c_str()); //一个或是一串数字字符转化为浮点数
			digitStack.push(number);
		}
		else if (postfix_Expression[i] == "+") {
			if (!digitStack.empty()) {
				op2 = digitStack.top();
				digitStack.pop();
			}
			if (!digitStack.empty()) {
				op1 = digitStack.top();
				digitStack.pop();
			}
			digitStack.push(op1 + op2);
		}
		else if (postfix_Expression[i] == "-") {
			if (!digitStack.empty()) {
				op2 = digitStack.top();
				digitStack.pop();
			}
			if (!digitStack.empty()) {
				op1 = digitStack.top();
				digitStack.pop();
			}
			digitStack.push(op1 - op2);
		}
		else if (postfix_Expression[i] == "*") {
			if (!digitStack.empty()) {
				op2 = digitStack.top();
				digitStack.pop();
			}
			if (!digitStack.empty()) {
				op1 = digitStack.top();
				digitStack.pop();
			}
			digitStack.push(op1 * op2);
		}
		else if (postfix_Expression[i] == "/") {
			if (!digitStack.empty()) {
				op2 = digitStack.top();
				digitStack.pop();
			}
			if (!digitStack.empty()) {
				op1 = digitStack.top();
				digitStack.pop();
			}
			/*if (op2 == 0) {
				error = true;
				return;
			}*/
			digitStack.push(op1 / op2);
		}
		
		else if (postfix_Expression[i] == "^") {
			if (!digitStack.empty()) {
				op2 = digitStack.top();
				digitStack.pop();
			}
			if (!digitStack.empty()) {
				op1 = digitStack.top();
				digitStack.pop();
			}
			digitStack.push(pow(op1, op2));
		}
	}
	if (!digitStack.empty()) {
		result = digitStack.top();
	}
}

//计算方法
void Calculator::OperationalProcess() {
	initializeResult();
	getFormat();				//表达式自定义标准格式化

	getPostfix();				//后缀表达式转换

	calResult();				//获取算术结果
	/*
	try {
		calResult();			//计算
	}
	catch (char) {
		cout << "除数不能为零!" << endl;
		return ;
	}*/
	/*if (error) {
		cout << "除数不能为零" << endl;
		return ;
	}*/
	
	cout << "原式=" << result << endl;
}

void Calculator::initializeResult() {
	result = 0.0;
	//error = false;
}

main.cpp

#include <iostream>
#include "Calculator.h"
using namespace std;

int main()
{
	Calculator t_calculator;
	cout << "-------------------------------------------------" << endl;
	cout << t_calculator.systemExplanation << endl;
	cout << "-------------------------------------------------" << endl;

	while (1) {
		getline(cin, t_calculator.expressionBuffer);
		t_calculator.OperationalProcess();
	}
	return 0;
}

以上是关于[c++] 一个支持安装卸载,复杂运算的简易计算器的主要内容,如果未能解决你的问题,请参考以下文章

任务02——安装 Intellj IDEA,编写一个简易四则运算小程序,并将代码提交到 GitHub

JS实现简易的计算器

用c++做一个四则运算计算器(支持加减乘除混合运算,支持括号,倒数,正负号),跪求

C++ 简易加减乘除运算(九度OJ 1116)

支持复杂运算的计算器SpeedCrunch

Java 简易计算器代码(只能整数的简易运算)