[c++] 一个支持安装卸载,复杂运算的简易计算器
Posted 泥烟
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[c++] 一个支持安装卸载,复杂运算的简易计算器相关的知识,希望对你有一定的参考价值。
这是大一放假前最后做的一个小玩意,现在抽空整理了一下,纪念自己第一个作品
目录
一.技术栈,开发工具
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