四则运算与赋值运算的计算器实现

这篇博客回顾了作者2018年完成的一个计算概论大作业,即编写一个支持赋值运算和四则运算的计算器。计算器能够处理数学公式,如加减乘除、括号、三角函数等,同时也展示了处理错误情况,如除数为0的错误提示。
摘要由CSDN通过智能技术生成

 这是我2018年初上计算概论写的大作业。现在回看,哎。。当时怎么写成这样=__= 这当作一个黑历史吧,警醒我代码也能丑成这样。

题目是让我们写一个能实现赋值运算和四则运算的计算器,包括一些难的数学公式。

>>x=3+3*7

>>>24

>>y+3

>>>error

>>cos(3*9-27)/2+4

>>>4.5

>>2333333334/(8-9+1)

>>>error                  (除数为0)

>>x=x+3

>>>27

>>y=90

>>x+y

>>>117

>>2^10

>>>1024

#include<iostream>
#include<iomanip>
#include<cstring>
#include<cmath>
#include<stack>
#include<algorithm>
#include<sstream>
#include<windows.h>
using namespace std;
HANDLE hout;
#define M_PI 3.14159265358979323846
#define maxnum 12
string  keys[maxnum];
string values[maxnum];

string keys1[7] = { "arcsin","arccos","arctan","sqrt" ,"sin","cos","tan" };
string values1[7] = { "%","`","?","~" , "!","@","$" };
int assignmentstring = 0;//变量的总个数
int len;

char Prior[17][17] =  // 运算符优先级表
{
	          // '+' '-'   '*'  '/'  '='  '('  ')'  '#' '^','sin','cos','tan','asin','acos','atan','sqrt'
       { '>', '>', '>', '>', '>', '<','<', '<', '<' ,'>','>','>'},
/*'+'*/{ '>', '>', '>', '<', '<', '<','<', '>', '>','<','<','<','<','<','<','<' },
/*'-'*/{ '>', '>', '>', '<', '<','<', '<', '>', '>','<','<','<','<','<','<','<' },
/*'*'*/{ '>', '>', '>', '>', '>','<', '<', '>', '>','<','<','<','<','<','<','<' },
/*'/'*/{ '>', '>', '>', '>', '>', '<','<', '>', '>' ,'<','<','<','<','<','<','<'},
/*'='*/{ '>', '>', '>', '>', '>', '>','>', '>', '>' ,'>', '>', '>','>', '>', '>' ,'>'},
/*'('*/{ '>', '<', '<', '<', '<', '<','<', '=', '<','<', '<', '<',  '<', '<', '<', '<','<'},
/*')'*/{ '>', '>', '>', '>', '>', '<',' ', '>', '>', '>', '>', '>', '>', '>', '>', '>','>'},
/*'#'*/{ '>', '<', '<', '<', '<', '<','<', '>', '=','<' , '<', '<', '<', '<', '<','<'},
/*'^'*/{ '>', '>', '>', '>', '>','<', '<', '>', '>','>', '>','>','>','>','>','>'},
/*'sin'*/{ '>', '>', '>', '>', '>','<', '<', '>', '>','<', '>', '>','>', '>', '>' ,'>' },
/*"cos"*/{ '>', '>', '>', '>', '>','<', '<', '>', '>','<' , '>', '>','>', '>', '>' ,'>'},
/*tan */ { '>', '>', '>', '>', '>','<', '<', '>', '>','<', '>', '>','>', '>', '>' ,'>' },
/*asin*/ { '>', '>', '>', '>', '>','<', '<', '>', '>','<', '>', '>','>', '>', '>' ,'>' },
/*acos*/ { '>', '>', '>', '>', '>','<', '<', '>', '>','<' , '>', '>','>', '>', '>' ,'>'},
/*atan*/{ '>', '>', '>', '>', '>','<', '<', '>', '>','<', '>', '>','>', '>', '>' ,'>' },
/*sqrt*/{ '>', '>', '>', '>', '>','<', '<', '>', '>','<', '>', '>','>', '>', '>' ,'>' },
};

int judge(char c)
{
	switch (c)
	{
	case'+':return 1;
	case'-':return 2;
	case'*':return 3;
	case'/':return 4;
	case'=':return 5;
	case'(':return 6;
	case')':return 7;
	case'#':return 8;
	case'^':return 9;
	case'!':return 10;
	case'@':return 11;
	case'$':return 12;
	case'%':return 13;
	case'?':return 14;
	case'~':return 15;
	case'`':return 16;
	default:return 0;
	}
}
//优先级比较
char precede(char m, char n)
{
	int a, b;
	a = judge(m);
	b = judge(n);
	return Prior[a][b];
}
//括号匹配
bool kuohao_pipei(string &exp1)
{
	int leftt = 0, len = exp1.length();
	for (int i = 0; i < len; i++)
	{
		if (exp1[i] == '(')
		{
			leftt++;
		}
		if (exp1[i] == ')')
		{
			leftt--;
		}
		if (leftt < 0)
		{
			SetConsoleTextAttribute(hout, FOREGROUND_INTENSITY | FOREGROUND_GREEN);
			cout << ">>";
			SetConsoleTextAttribute(hout, FOREGROUND_INTENSITY | FOREGROUND_RED);
			cout << "error" << endl;
			return false;
		}
	}
	if (leftt != 0)
	{
		SetConsoleTextAttribute(hout, FOREGROUND_INTENSITY | FOREGROUND_GREEN);
		cout << ">>";
		SetConsoleTextAttribute(hout, FOREGROUND_INTENSITY | FOREGROUND_RED);
		cout << "error" << endl;
		return false;
	}
	else
		return true;

}
//符号计算
long double mul(long double a, long double b, char c)
{
	switch (c)
	{
	case '+':
		return b + a;
	case '-':
		return b - a;
	case '*':
		return b * a;
	case '/':
		return b / a;
	case'^':
		return pow(b, a);
		//'sin', 'cos', 'tan', 'asin', 'acos', 'atan'
	case'!':return sin(a);
	case'@':return cos(a);
	case'$':return tan(a);
	case'%':return asin(a);
	case'`':return acos(a);
	case'?':return atan(a);
	case'~':return sqrt(a);
	default:
		return -1;
	}
}
//判断是否是运算符
bool Comop(char ch) 
{
	switch (ch)
	{
	case'+':
	case'-':
	case'*':
	case'/':
	case'(':
	case')':
	case'#':
	case'^':
	case'~':
	case'!':
	case'@':
	case'$':
	case'%':
	case'`':
	case'?':
		return true;
	default:
		return false;
	}
}//判断ch是否为运算符

//中缀表达式转换后缀表达式
void TransmitExpression(string &exp1, string &posexp1)
{
	stack<char>q2;
	int i = 0;
	q2.push('#');
	len = exp1.length();

	while (i < len)
	{
		if (!Comop(exp1[i]))
		{
			string a = "3";
			while ((exp1[i] >= '0'&&exp1[i] <= '9') || exp1[i] == '.')//读取一个数字串
			{
				a[0] = exp1[i++];
				posexp1 += a;
			}
			posexp1 += "#";
		}
		else
		{
			switch (precede(q2.top(), exp1[i]))
			{
			case'<':
				q2.push(exp1[i]);
				i++;
				break;
			case'=':
				q2.pop();
				i++;
				break;
			case'>':
				string a = "3";
				a[0] = q2.top();
				posexp1 += a;
				q2.pop();
				break;
			}
		}
	}
	while (q2.top() != '#')
	{
		string a = "3";
		a[0] = q2.top();
		posexp1 += a;
		q2.pop();
	}
}
//后缀表达式的计算
long double EvaluateExpression(string &posexp1)
{
	stack<long double>q1;
	long double a, b, d;
	int kk = posexp1.length();
	int i = 0;
	while (i < kk)
	{
		switch (posexp1[i])
		{
		case'+':
		case'-':
		case'*':
		case'/':
		case'^':
		case'~':
		case'!':
		case'@':
		case'$':
		case'%':
		case'`':
		case'?':
			a = q1.top();
			q1.pop();
			b = q1.top();
			q1.pop();
			q1.push(mul(a, b, posexp1[i]));
			break;
		default:
			d = 0;
			int zz = 1;
			long double ss = 0.1;
			while ((posexp1[i] >= '0'&&posexp1[i] <= '9') || (posexp1[i] == '.'))//计算数值
			{
				if (posexp1[i] == '.')
				{
					zz = 0;
					i++;
					continue;
				}
				if (zz == 1) {
					d = 10 * d + posexp1[i] - '0';
				}

				if (zz == 0)
				{
					d += ss * (posexp1[i] - '0');
					ss *= 0.1;
				}
				i++;
			}
			q1.push(d);
			break;
		}
		i++;
	}
	return q1.top();
}
string&   replace_all_distinct(string&   str, const   string&   old_value, const   string&   new_value)
{
	for (string::size_type pos(0); pos != string::npos; pos += new_value.length()) {
		if ((pos = str.find(old_value, pos)) != string::npos)
			str.replace(pos, old_value.length(), new_value);
		else   break;
	}
	return   str;
}

void replace_variables(string &exp1)
{
	string aa = "(";
	string bb = ")";
	for (int i = 0; i < assignmentstring; i++)
		if (exp1.find(keys[i]) != string::npos)
		{
			exp1 = replace_all_distinct(exp1, keys[i], aa + values[i] + bb);
		}
	for (int i = 0; i < 7; i++)
	{
		if (exp1.find(keys1[i]) != string::npos)
		{
			exp1 = replace_all_distinct(exp1, keys1[i], values1[i]);
		}
	}
}

bool error(string &exp1)
{
	int k, i = 0;
	int tt = exp1.length();
	while (i < tt)
	{

		k = judge(exp1[i]);

		if (
			(((k >= 1 && k <= 5) || exp1[i] == '.'||(k>=9&&k<=15)) && (exp1[i + 1] == ')'))
			|| (((k > 2 && k <= 5) || exp1[i] == '.' || k == 1|| (k >= 9 && k <= 16)) && (exp1[i - 1] == '('))//(-1*2)这样是正确的
			|| (exp1[i] == ')'&&exp1[i + 1] == '(')
			|| (exp1[i] == '('&&exp1[i + 1] == ')')
			|| ((exp1[i] == ')') && exp1[i + 1] >= '0'&& exp1[i + 1] <= '9')
			|| (exp1[i] >= '0'&&exp1[i] <= '9'&&exp1[i + 1] == '(')
			|| (exp1[0] == '+' || exp1[0] == '*' || exp1[0] == '/' || exp1[0] == ')' || exp1[0] == '='||
				exp1[0] == '^'||exp1[0]=='~'|| exp1[0] == '~' || exp1[0] == '!' || exp1[0] == '@' ||
				exp1[0] == '$' || exp1[0] == '%' || exp1[0] == ']' || exp1[0] == '?')
			|| ((exp1[i] == '+' || exp1[i] == '-' || exp1[i] == '*' || exp1[i] == '/' || exp1[i] == '='||exp1[i] == '^' || exp1[i] == '~' || exp1[i] == '~' || exp1[i] == '!' || exp1[i] == '@' ||
				exp1[i] == '$' || exp1[i] == '%' || exp1[i] == '`' || exp1[i] == '?') && (exp1[i + 1] == '+' || exp1[i + 1] == '*' || exp1[i + 1] == '/' || exp1[i + 1] == '-' || exp1[i+1] == '='|| exp1[i+1] == '^' || exp1[i+1] == '~' || exp1[i+1] == '~' || exp1[i+1] == '!' || exp1[i+1] == '@' ||
					exp1[i+1] == '$' || exp1[i+1] == '%' || exp1[i+1] == '`' || exp1[i+1] == '?'))
			|| (exp1[i] == '/'&&exp1[i + 1] == '0')
			|| ((exp1[i] == '+' || exp1[i] == '-' || exp1[i] == '*' || exp1[i] == '/'|| exp1[i] == '^') && (exp1[i + 1] == '+' || exp1[i + 1] == '*' || exp1[i + 1] == '/' || exp1[i + 1] == '='|| exp1[i+1] == '^'))
			|| (exp1[i] == '.' && (exp1[i + 1]<'0' || exp1[i + 1]>'9'))
			|| (exp1[i] == '.' && (exp1[i - 1]<'0' || exp1[i - 1]>'9'))
                                                ||(i==exp1.length()-1&&(exp1[i] == '+' || exp1[i] == '-' || exp1[i] == '*' || exp1[i] == '/' || exp1[i] == '='||exp1[i] == '^' || exp1[i] == '~' || exp1[i] == '~' || exp1[i] == '!' || exp1[i] == '@' ||
				exp1[i] == '$' || exp1[i] == '%' || exp1[i] == '`' || exp1[i] == '?'))
			)
			return false;
		else {
			if (i == len)
				return true;
		}
		i++;
	}
	return true;
}

int judge1(char a)
{
	if (a == '_' || (a >= '0'&&a <= '9') || (a >= 'a'&&a <= 'z') || (a >= 'A'&&a <= 'Z'))return 1;
	return 0;
}

bool judge_name(string &a)
{
	int k, i, flag = 0;
	k = a.length();
	if (a[0] >= '0'&& a[0] <= '9')return false;//首字母不是数字
	for (i = 0; i < k; i++)
	{
		if (flag == 0 && (a[i]<'0' || a[i]>'9')) flag = 1;//保证不全是数字
		if (a[i] == '_' || (a[i] >= '0'&&a[i] <= '9') || (a[i] >= 'a'&&a[i] <= 'z') || (a[i] >= 'A'&&a[i] <= 'Z'))
			continue;
		else
			return false;
	}
	if (flag == 0)return false;
	return true;
}

bool judge_value(string &b)
{
	int k = b.length();
	int t = 0;
	if (b[0] == '-')
	{
		t = 1;
		if (b[1] == '.' || b[k - 1] == '.')
			return false;
	}
	if (b[t] == '.' || b[k - 1] == '.')
		return false;
	int num = 0;

	for (int i = t; i < k; i++)
	{
		if (b[i] == '.')num++;
		if (b[i] >= '0'&&b[i] <= '9' || b[i] == '.')
			continue;
		return false;
	}
	if (num >= 2)return false;
	return true;
}

long double turnnum(string aa)
{
	long double d = 0, ss = 0.1;
	int i = 0, zz = 1, mm = 1;
	int length1 = aa.length();
	if (aa[0] == '-')
	{
		i = 1;
		mm = -1;
	}
	if (aa[0] == '+')
	{
		i = 1;
		mm = 1;
	}
	while (i < length1)
	{
		if (aa[i] == '.')
		{
			zz = 0;
			i++;
			continue;
		}
		if (zz == 1) {
			d = 10 * d + (aa[i] - '0');
		}
		if (zz == 0)
		{
			d += ss * (aa[i] - '0');
			ss *= 0.1;
		}
		i++;
	}
	return d * mm;
}
bool judge_othervarialbes(string &exp1)
{

	int k = exp1.length();
	for (int i = 0; i < k; i++)
	{
		if ((exp1[i] >= '0' && exp1[i] <= '9') || (judge(exp1[i]) >= 1 && judge(exp1[i]) <= 7) || exp1[i] == '.'|| exp1[i] == '^' || exp1[i] == '~' || exp1[i] == '!' || exp1[i] == '@' ||
			exp1[i] == '$' || exp1[i] == '%' || exp1[i] == '`' || exp1[i] == '?')
			continue;
		else
		{
			SetConsoleTextAttribute(hout, FOREGROUND_INTENSITY | FOREGROUND_GREEN);
			cout << ">>";
			SetConsoleTextAttribute(hout, FOREGROUND_INTENSITY | FOREGROUND_RED);
			cout << "error1" << endl;
			return false;
		}
	}
	return true;
}
string doubleToString(long double num)
{
	ostringstream out;
	int prec = 100;
	out.precision(prec);
	out << num;
	string str = out.str();
	size_t n = str.find('.');
	if (n != string::npos&&str.size() > n + 50)
	{
		str[n + 50] = '\0';
	}
	string temp = str.c_str();
	str = temp;
	return str;
}
int judge4(char c)
{
	switch (c)
	{
	case'+':return 1;
	case'-':return 2;
	case'*':return 3;
	case'/':return 4;
	case'=':return 5;
	default:return 0;
	}
}
void mysorted()
{
	for (int i = 0; i < assignmentstring - 1; i++)
	{
		for (int j = 0; j < assignmentstring - 1 - i; j++)
		{
			if (keys[j].length() < keys[j + 1].length())
			{
				swap(keys[j], keys[j + 1]);
				swap(values[j], values[j + 1]);
			}
		}
	}
}
void change(string &aa)
{
	int k = aa.length();
	int i = 0;
	while (i < k)
	{
		if (aa[i] == '-'&&i == 0)
		{
			aa.insert(aa.begin(), '0');
			k++;
		}
		else if (i < k - 1 && aa[i] == '('&&aa[i + 1] == '-')
		{
			aa.insert(aa.begin() + (i + 1), '0');
			k++;
		}
		i++;
	}
} 
int insertdd(int x,string &aa)
{
	int k = 0;
	for (int i = x; i < aa.length(); i++)
	{
		if (aa[i] == '(')k++;
		if ((k == 0 && judge4(aa[i])) || (aa[i] == ')'&&k == 1))return i;
		if (aa[i] == ')')k--;
	}
return-1;
}
void changesin(string &aa)
{
	int k = aa.length();
	int i = 0;
	while (i < k)
	{
		if ((aa[i] == '~'||aa[i]=='!'||aa[i]=='$'||aa[i]=='%'||aa[i]=='`'||aa[i]=='?'||aa[i]=='@'))
		{
			aa.insert(aa.begin() +i, '(');
			k++;
		
			aa.insert(aa.begin() +i + 1, '0');
				k++;
	
				int tt = insertdd(i + 3, aa);
				if (tt != -1)
				{
					aa.insert(aa.begin() + tt, ')');
				}
				if (tt == -1)
				{
					aa += ")";
				}
				k++;
				i = i + 3;
			
				continue;
		}
		
		i++;
	}
}
bool panpan(string &exp)//判断赋值语句是否有多个=
{
	int cnt = 0, len = exp.length();
	for (int i = 0; i < len; i++)
	{
		if (exp[i] == '=')
			cnt++;
	}
	if (cnt == 1)
		return true;
	else
		return false;
}
bool zero(string &b)
{
	int kk = 0;
	for (int i = 0; i < b.length(); i++)
	{
		if (b[i] == '/'&&b[i + 1] == '(')
		{
			kk++;
			for (int k = i + 2; k < b.length(); k++)
			{
				if (b[k] == ')')
				{
					kk--;
					if (kk == 0)
					{
						string aa = b.substr(i + 1, k);
						string bbb;
						TransmitExpression(aa, bbb);
						long double c = EvaluateExpression(bbb);
						if (c == 0)return false;
						i = k + 1;
						break;
					}
				}
			}
		}
	}
	return true;
}
bool assignment(string &exp)//赋值语句
{
	len = exp.length();
	if (exp.find("=") == string::npos)return true;
	if (!panpan(exp))
	{
		SetConsoleTextAttribute(hout, FOREGROUND_INTENSITY | FOREGROUND_GREEN);
		cout << ">>";
		SetConsoleTextAttribute(hout, FOREGROUND_INTENSITY | FOREGROUND_RED);
		cout << "error2" << endl;
		return false;
	}
	int pos = exp.find("=");
	string a = exp.substr(0, pos);
	string b = exp.substr(pos + 1, len - 1);
	replace_variables(b);//替换变量
	changesin(b);

	if (!judge_othervarialbes(b))
	{
		return false;
	}
	if (judge_value(b))
	{
		for (int i = 0; i < assignmentstring; i++)
		{
			if (keys[i] == a)
			{
				values[i] = b;
				long double c = turnnum(b);
				if (abs(long long(c) - c) < 1e-6)
				{
					SetConsoleTextAttribute(hout, FOREGROUND_INTENSITY | FOREGROUND_GREEN);
					cout << ">>";
					SetConsoleTextAttribute(hout, FOREGROUND_INTENSITY | FOREGROUND_RED);
					cout << long long(c) << endl;
				}
				else
				{
					SetConsoleTextAttribute(hout, FOREGROUND_INTENSITY | FOREGROUND_GREEN);
					cout << ">>";
					SetConsoleTextAttribute(hout, FOREGROUND_INTENSITY | FOREGROUND_RED);
					cout << setprecision(2) << c << endl;
				}

				return false;
			}
		}//如果a不在key中看a是否合法
		if (judge_name(a))
		{
			keys[assignmentstring] = a;
			values[assignmentstring] = b;
			long double c = turnnum(b);
			
			if (abs(long long(c) - c) < 1e-6)
			{
				SetConsoleTextAttribute(hout, FOREGROUND_INTENSITY | FOREGROUND_GREEN);
				cout << ">>";
				SetConsoleTextAttribute(hout, FOREGROUND_INTENSITY | FOREGROUND_RED);
				cout << long long(c) << endl;
			}
			else
			{
				SetConsoleTextAttribute(hout, FOREGROUND_INTENSITY | FOREGROUND_GREEN);
				cout << ">>";
				SetConsoleTextAttribute(hout, FOREGROUND_INTENSITY | FOREGROUND_RED);
				cout << fixed << setprecision(2) << c << endl;
			}
			assignmentstring++;
			mysorted();
			return false;
		}
		else
		{
			SetConsoleTextAttribute(hout, FOREGROUND_INTENSITY | FOREGROUND_GREEN);
			cout << ">>";
			SetConsoleTextAttribute(hout, FOREGROUND_INTENSITY | FOREGROUND_RED);
			cout << "error3" << endl;
			return false;
		}
	}
	//如果以上不成立,那么b又是另一个赋值运算
	if (!error(b))
	{
		SetConsoleTextAttribute(hout, FOREGROUND_INTENSITY | FOREGROUND_GREEN);
		cout << ">>";
		SetConsoleTextAttribute(hout, FOREGROUND_INTENSITY | FOREGROUND_RED);
		cout << "error4" << endl;
		return false;
	}
	else //如果他是一个正确的表达式
	{
		change(b);
		if (!zero(b))
		{
			SetConsoleTextAttribute(hout, FOREGROUND_INTENSITY | FOREGROUND_GREEN);
			cout << ">>";
			SetConsoleTextAttribute(hout, FOREGROUND_INTENSITY | FOREGROUND_RED);
			cout << "error5" << endl;
			return false;
		}
		string mm;
		TransmitExpression(b, mm);
		long double c = EvaluateExpression(mm);
		b = doubleToString(c);
		for (int i = 0; i < assignmentstring; i++)
		{
			if (keys[i] == a)
			{
				values[i] = b;
				if (abs(long long (c)-c)<1e-6)
				{
					SetConsoleTextAttribute(hout, FOREGROUND_INTENSITY | FOREGROUND_GREEN);
					cout << ">>";
					SetConsoleTextAttribute(hout, FOREGROUND_INTENSITY | FOREGROUND_RED);
					cout << long long(c) << endl;
				}
				else
				{
					SetConsoleTextAttribute(hout, FOREGROUND_INTENSITY | FOREGROUND_GREEN);
					cout << ">>";
					SetConsoleTextAttribute(hout, FOREGROUND_INTENSITY | FOREGROUND_RED);
					cout << fixed << setprecision(2) << c << endl;
				}


				return false;
			}
		}
	}
	if (judge_name(a))
	{
		keys[assignmentstring] = a;
		values[assignmentstring] = b;
		long double c = turnnum(b);
		if (abs(long long(c)-c)<1e-6)
		{
			SetConsoleTextAttribute(hout, FOREGROUND_INTENSITY | FOREGROUND_GREEN);
			cout << ">>";
			SetConsoleTextAttribute(hout, FOREGROUND_INTENSITY | FOREGROUND_RED);
			cout <<long long( c) << endl;
		}
		else
		{
			SetConsoleTextAttribute(hout, FOREGROUND_INTENSITY | FOREGROUND_GREEN);
			cout << ">>";
			SetConsoleTextAttribute(hout, FOREGROUND_INTENSITY | FOREGROUND_RED);
			cout << fixed << setprecision(2) << c << endl;
		}
		assignmentstring++;
		mysorted();
		return false;
	}
	else
	{
		SetConsoleTextAttribute(hout, FOREGROUND_INTENSITY | FOREGROUND_GREEN);
		cout << ">>";
		SetConsoleTextAttribute(hout, FOREGROUND_INTENSITY | FOREGROUND_RED);
		cout << "error6" << endl;
		return false;
	}
}
void trim(string &exp)//去空格
{
	if (!exp.empty())
	{
		exp.erase(0, exp.find_first_not_of(" "));
		exp.erase(exp.find_last_not_of(" ") + 1);
	}
	int index = 0;
	if (!exp.empty())
	{
		while ((index = exp.find(' ', index)) != string::npos)
		{
			exp.erase(index, 1);
		}
	}
}

bool judge_blank(string &exp)
{

	for (int i = 0; i < len; i++)//判断是不是出现5 6*8类似这样的情况
	{
		if (i + 2 < len && judge1(exp[i]) && exp[i + 1] == ' '&& judge1(exp[i + 2]))
		{
			SetConsoleTextAttribute(hout, FOREGROUND_INTENSITY | FOREGROUND_GREEN);
			cout << ">>";
			SetConsoleTextAttribute(hout, FOREGROUND_INTENSITY | FOREGROUND_RED);
			cout << "error7" << endl;
			return false;
		}
	}
	trim(exp);
	len = exp.length();
	return true;
}

int insertkuohao(int x, string &exp1)
{
	int k = 0;
	for (int i = x; i < exp1.length(); i++)
	{
		if (exp1[i] == '(')k++;
		if ((k == 0 && judge4(exp1[i])) || (exp1[i] == ')'&&k == 1))return i;
		if (exp1[i] == ')')k--;
	}
	return -1;
}
void change1(string &exp1)//保障负数的正确运算
{

	int kk = exp1.length();
	for (int i = 1; i < kk; i++)
	{
		if (judge4(exp1[i]) == 2 && (judge4(exp1[i - 1]) != 2 && judge4(exp1[i - 1]) != 0))
		{

			exp1.insert(exp1.begin() + i, '(');
			int k = insertkuohao(i + 2, exp1);
			if (k != -1)
			{
				exp1.insert(exp1.begin() + k, ')');
			}
			if (k == -1)
			{
				exp1 += ')';
			}
			kk++;
		}
	}
}

int main()
{
	hout = GetStdHandle(STD_OUTPUT_HANDLE);
	while (1)
	{
		string exp;
		string posexp;
		SetConsoleTextAttribute(hout, FOREGROUND_INTENSITY | FOREGROUND_GREEN);//绿色的箭头
		cout << ">>";
		SetConsoleTextAttribute(hout, FOREGROUND_INTENSITY);//输入为原来的颜色
		getline(cin, exp);
		if (exp == "exit")
			return 0;
		len = exp.length();
		if (exp[len - 1] == ';') {
			exp = exp.substr(0, len - 1);
		}
		len = exp.length();
		if (!judge_blank(exp)) continue;//判断出现空格的地方是否错误
		if (!kuohao_pipei(exp)) continue;//判断是否括号匹配
		change1(exp);//保证负数运算的正确性
		
		if (!assignment(exp)) continue;//判断并处理赋值语句
		replace_variables(exp);//替换变量
		
		changesin(exp);
	len= exp.length();
		if (!judge_othervarialbes(exp))continue;//判断还有其他未出现的变量
		if (error(exp))
		{
			change(exp);
			len = exp.length();
			if (!zero(exp))
			{
				cout << exp << endl;
				SetConsoleTextAttribute(hout, FOREGROUND_INTENSITY | FOREGROUND_GREEN);
				cout << ">>";
				SetConsoleTextAttribute(hout, FOREGROUND_INTENSITY | FOREGROUND_RED);
				cout << "error8" << endl;
				continue;
			}
			len=exp.length();
			
			TransmitExpression(exp, posexp);
			
			long double c = EvaluateExpression(posexp);
			if (abs(long long(c) - c) < 1e-6)
			{
				SetConsoleTextAttribute(hout, FOREGROUND_INTENSITY | FOREGROUND_GREEN);
				cout << ">>";
				SetConsoleTextAttribute(hout, FOREGROUND_INTENSITY | FOREGROUND_RED);
				cout << long long(c) << endl;
				
			}
			else
			{
				
					SetConsoleTextAttribute(hout, FOREGROUND_INTENSITY | FOREGROUND_GREEN);
					cout << ">>";
					SetConsoleTextAttribute(hout, FOREGROUND_INTENSITY | FOREGROUND_RED);
					cout << fixed << setprecision(2) << c << endl;
			}
		}
		else
		{
			SetConsoleTextAttribute(hout, FOREGROUND_INTENSITY | FOREGROUND_GREEN);
			cout << ">>";
			SetConsoleTextAttribute(hout, FOREGROUND_INTENSITY | FOREGROUND_RED);
			cout << "error9" << endl;
		}
	}
	return 0;
}

 

calculator.cpp 能够实现四则运算和乘方运算赋值及报错的计算器 2018-12-4 -------------------------------------------------- 本程序的输入有三类:指令、赋值语句和计算式 这三类输入均允许在基本元素之间添加任意数目的空格 当出现错误时,本程序会显示Error并给出报错原因 ·指令 指令包含以下三个 exit 退出程序 printvar 输出所有已定义的变量及其值 emptyvar 清除所有变量 所有变量名不能与指令重名 ·赋值语句 基本格式为 变量名=数值 其中“数值”可以是一行计算式 ·计算式 所有非指令和赋值语句都会作为计算式进行计算 本程序可以对输入的一行计算式的值进行计算并输出答案 按照题目要求,若结果为整数,将输出整数;若结果为浮点数,将保留两位小数 计算式中可以包含变量、数字和运算符号 计算式直接以运算符开头会报错“出现连续的运算符”,但如果以+-直接开头会被认作数的正负符号 -------------------------------------------------- 输入的基本元素包括变量、数字和运算符号 ·变量名 变量名必须以字母或下划线开头,由字母、数字或下划线组成,不能与指令重名 ·数字 可以是整数或者小数,当然也包括用/表示的分数 暂不支持除十进制外其他进制的输入 支持.23这样的省略整数部分0的输入 支持32.这样的输入 但是.不会被认为是0而会报错 ·运算符号 包括 加号+ 减号- 乘号* 除号/ 括号( ) 乘方^ 其中除数不能为零 乘方的底数是负数时,指数需要是整数 零的零次幂没有意义 -------------------------------------------------- 请注意 请在输入时务必使用英文输入或选择半角字符! 当语句中出现多个错误时,只会提示最先发现的错误 与c/c++表达式计算不同的地方: 本程序输出时会将整数相除产生的浮点数自动进行类型转换成浮点数,也会将浮点数运算得到的整数自动类型转换成整数,也就是说1/2=0.50,2.0/1.0=2(c++的自动取整真的很蠢) c/c++为了避免与函数冲突,不允许a(b+c),2(3+1)这样的法,而本程序会默认在括号前进行了乘法运算,即2(3+1)=2*(3+1)=8,a(b+c)=a*(b+c) cmath中的pow函数对于0的0次方会返回1,但是0的0次方是没有意义的,本程序会对0^0报错 鉴于c++支持+-+-+-1=-1,但是出现连+或连-时会报错的混乱情况,本程序允许在数字和变量前加一个+或-号用来变号,即2+-1 3*-x -3++2是支持的,但是多于一个的额外+-号将报错,即3+-+2 +-1是不支持的 --------------------------------------------------
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值