⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 expression.cpp

📁 表达式处理及数制转换
💻 CPP
字号:
/*
  Expression.cpp
  基于命令行的四则运算计算器
  同时可以实现进制(Dec,Hex,Bin,Oct)之间的相互转换
  为简约起见,我没有加入高精度运算的环节
*/

//By phoenixinter
//On 12/12/2004

#include<stdio.h>
#include<string.h>
#include<stdlib.h>

#define STACKSIZE 100			//表达式的最长字符数
int topt=-1,topd=-1;			//Stack Pointer
double opnd[STACKSIZE];			//数字栈
char oprt[STACKSIZE];			//符号栈
char expression[STACKSIZE];		//存储表达式
int ismistake=0;				//判断输入的表达式是否有语法错误

double chiaus;
void convert();

void pushopnd(double x)			//数字压栈
{
	if(topd==STACKSIZE-1)
	{
		printf("Operand Stack overflow!\n");
		exit(-1);
	}
	opnd[++topd]=x;
}

void pushoprt(char x)			//符号压栈
{
	if(topt==STACKSIZE-1)
	{
		printf("Operator Stack overflow!\n");
		exit(-1);
	}
	oprt[++topt]=x;
}

double popopnd()				//数字出栈
{
	if(topd==-1)
	{
		printf("Operand Stack underflow!\n");
		exit(-1);
	}
	return(opnd[topd--]);
}

char popoprt()					//符号出栈
{
	if(topt==-1)
	{
		printf("Operator Stack underflow!\n");
		exit(-1);
	}
	return(oprt[topt--]);
}

double getopnd()				//取得数字栈的栈顶元素
{
	if(topd==-1)
	{
		printf("Operand Stack underflow!\n");
		exit(-1);
	}
	return(opnd[topd]);
}

char getoprt()					//取得符号栈的栈顶元素
{
	if(topt==-1)
	{
		printf("Operator Stack underflow!\n");
		exit(-1);
	}
	return(oprt[topt]);
}

char priority(char c1,char c2)	//比较符号优先级
{
	if((c1=='*'||c1=='/')&&(c2!='(')) return '>';
	if((c1=='+'||c1=='-')&&(c2=='+'||c2=='-'||c2==')'||c2=='\0' )) return '>';
	if((c1=='+'||c1=='-')&&(c2=='*'||c2=='/'||c2=='(')) return '<';
	if((c1=='*'||c1=='/')&&(c2=='(')) return '<';
	if(c1=='('&&c2!=')') return '<';
	if(c1=='('&&c2==')') return '=';
	if(c1==')') return '>';
	if(c1=='\0'&&c2=='\0') return '=';
	if(c1=='\0'&&c2!='\0') return '<';
}

double calculate(double a,char symbol,double b)		//执行单个符号的计算
{
	double result;
	if(symbol=='+') result=a+b;
	if(symbol=='-') result=a-b;
	if(symbol=='*') result=a*b;
	if(symbol=='/') result=a/b;
	return result;
}

void initexpression()
{
	printf("Please input an arithmetic expression.\n");
	printf("Please don't input unwanted space or tab.\n");
	printf("Press Enter to finish your input:\n");
	scanf(" %s",expression);
}

void btod()
{
	int isfrac=0;
	char *p,s[20];
	double power=1,value=0;
	printf("Please input a binary:");
	scanf(" %s",s);
	p=s;
	while(*p!='\0')
	{
		if(*p=='.') isfrac=1;
		else if(isfrac==0)	
		{
			if(*p=='1')value=value*2+1;
			if(*p=='0')value=value*2;
		}
		else
		{
			power=power*2;
			if(*p=='1')value=value+1.0/power;
		}
		p++;
	}
	chiaus=value;
	printf("The decimal code is:");
	printf("%f\n",value);
}

void otod()
{
	int isfrac=0;
	char *p,s[20];
	double power=1,value=0;
	printf("Please input a octal:");
	scanf(" %s",s);
	p=s;
	while(*p!='\0')
	{
		if(*p=='.')
			isfrac=1;
		else if(isfrac==0)
			value=value*8+(double)(*p-48);
		else	
		{
			power=power*8;
			value=value+(double)(*p-48)/power;
		}
		p++;
	}
	chiaus=value;
	printf("The decimal code is:");
	printf("%f\n",value);
}

void htod()
{
	int isfrac=0;
	char *p,s[20];
	double power=1,value=0;
	printf("Please input a hexadecimal:");
	scanf(" %s",s);
	p=s;
	while(*p!='\0')
	{
		if(*p=='.')
			isfrac=1;
		else if(isfrac==0)
		{
			if(*p>='0'&&*p<='9')
				value=value*16+(double)(*p-48);
			else if(*p>='A'&&*p<='F')
				value=value*16+(double)(*p-55);
			else value=value*16+(double)(*p-87);
		}
		else
		{
			power=power*16;
			if(*p>'0'&&*p<='9')
				value=value+(double)(*p-48)/power;
			else if(*p>'A'&&*p<='F')
				value=value+(double)(*p-55)/power;
			else value=value+(double)(*p-87)/power;
		}
		p++;
	}
	chiaus=value;
	printf("The decimal code is:");
	printf("%f\n",value);
}

void dtob(double x)
{
	int num,i,a[64];
	long n,abn;
	double m;
	n=(long int)x;
	m=x-(long int)x;
	if(n>=0)abn=n;
	else abn=-n;
	for(i=0;i<16;i++)
	{
		if(abn%2==0) a[i]=0;
		else a[i]=1;
		abn=abn/2;
		if(abn==1)
		{
			a[++i]=1;
			num=i;
			break;
		}
	}
	printf("The binary code is:");
	for(i=num;i>=0;i--)
		printf("%d",a[i]);
	if(m!=0)
	{
		for(i=num+1;i<=num+6;i++)
			if(m*2>=1)
			{
				m=2*m-1;
				a[i]=1;
			}
			else
			{
				m=m*2;
				a[i]=0;
			}
			printf(".");
			for(i=num+1;i<num+7;i++)
				printf("%d",a[i]);
	}
	printf("\n");
}

void dtoo(double x)
{
	int num,i,a[16];
	long n,abn;
	double m;
	n=(long int)x;
	m=x-(long int)x;
	if(n>=0)abn=n;
	else abn=-n;
	for(i=0;i<16;i++)
	{
		if(abn%8==0)
			a[i]=0;
		else a[i]=abn%8;
		abn=abn/8;
        if(abn==0)
		{
			num=i;
			break;
		}
		if(abn<8)
		{
			a[++i]=abn;
			num=i;
			break;
		}
	}
	printf("The octal code is:");
	for(i=num;i>=0;i--)
		printf("%d",a[i]);
	if(m!=0)
	{
		for(i=num+1;i<=num+5;i++)
			if(m*8>=1)
			{
				a[i]=(int)(8*m);
				m=8*m-(int)(8*m);
			}
			else
			{
				m=m*8;
				a[i]=0;
			}
			printf(".");
			for(i=num+1;i<num+5;i++)
				printf("%d",a[i]);
	}
	printf("\n");
}

void dtoh(double x)
{
	int num,i;
	long n,abn,t;
	double m;
	char a[16];
	n=(long int)x;
	m=x-(long int)x;
	if(n>=0)abn=n;
	else abn=-n;
	for(i=0;i<16;i++)
	{
		t=abn%16;
		if(t==0) a[i]='0';
		else if(t>=0&&t<=9)a[i]=(char)(abn%16+48);
		else switch(t)
		{
		case 10:a[i]='A';break;
		case 11:a[i]='B';break;
		case 12:a[i]='C';break;
		case 13:a[i]='D';break;
		case 14:a[i]='E';break;
		case 15:a[i]='F';
		}
		abn=abn/16;
		if(abn==0){num=i;break;}
		if(abn<16)
		{
			i++;
			if(abn>0&&abn<=9)a[i]=(char)(abn%16+48);
			else
			{
				switch(abn)
				{
				case 10:a[i]='A';break;
				case 11:a[i]='B';break;
				case 12:a[i]='C';break;
				case 13:a[i]='D';break;
				case 14:a[i]='E';break;
				case 15:a[i]='F';
				}
			}
			num=i;
			break;
		}
	}

	printf("The hexadecimal code is:");
	for(i=num;i>=0;i--)
		printf("%c",a[i]);

	if(m!=0)
	{
		for(i=num+1;i<=num+4;i++)
			if(m*16>=1)
			{
				t=(int)(16*m);
				if(abn>=0&&t<=9)a[i]=(char)(t+48);
				else switch(abn)
				{
				case 10:a[i]='A';break;
				case 11:a[i]='B';break;
				case 12:a[i]='C';break;
				case 13:a[i]='D';break;
				case 14:a[i]='E';break;
				case 15:a[i]='F';
				}
				m=16*m-(int)(16*m);
			}
			else {m=m*16;a[i]=0;}
			printf(".");
			for(i=num+1;i<num+3;i++)
				printf("%c",a[i]);
	}
	printf("\n");
}

double dtod(char s[])
{
	int isfrac=0;
	char *p;
	double power=1,value=0;
	p=s;
	while(*p!='\0')
	{
		if(*p=='.') isfrac=1;
		else if(isfrac==0)value=value*10+(double)(*p-48);
		else
		{
			power=power*10;
			value=value+(double)(*p-48)/power;
		}
		p++;
	}
	return(value);
}

int judge(char a,char b)				//判断表达式相邻符号输入正误
{
	if((a=='+'||a=='-'||a=='*'||a=='/'||a=='.')&&(b=='+'||b=='-'||b=='*'||b=='/'||b=='.'||b==')'||b=='\0'))return 1;
	if((a=='(')&&(b==')'||b=='*'||b=='/'||b=='.'||b=='\0'))return 2;
	if((a==')')&&(b=='.'||b=='('||(b>='0'&&b<='9')))return 3;
	if(a>='0'&&a<='9'&&b=='(')return 4;
	else return 0;
}

void check()							//检查表达式拼写是否有误
{
	int i,j=0,a=0,b=0,lparenth=0,rparenth=0;
	char c,sign1,sign2;
	c=expression[0];
	sign1=c;

	if(c>='0'&&c<='9'||c>='('&&c<='+'||c=='.'||c=='-'||c=='/');
	else
	{
		ismistake=1;
		printf("Error 1! Invalid charactor!\n");
		goto end;
	} // Error 1

	if(c=='(') lparenth++;
	if(c=='.'||c==')'||c=='*'||c=='/')
	{
		ismistake=1;
		printf("Error 2! The first character cannot be '.',')','*','/'.\n");
		goto end;
	}// Error 2

	for(i=1;c!='\0';i++)
	{
		c=expression[i];
		if(c>='0'&&c<='9'||c>='('&&c<='+'||c=='.'||c=='-'||c=='/'||c=='\0');
		else
		{
			ismistake=1;
			printf("Error 1! Invalid charactor!\n");
			goto end;
		}
		sign2=c;
		j=judge(sign1,sign2);
		switch(j)
		{
		case 0:
			if(c=='.'&&b==0) a=1;
			if(a==1&&c>='0'&&c<='9') b=1;
			if(b==1&&c=='.')
			{
				ismistake=1;
				printf("Error 3! more than one dots in a number.\n");
				goto end;
			}// Error 3
			if(c=='+'||c=='-'||c=='*'||c=='/'||c==')')
			{
				a=0;
				b=0;
			}
			if(c=='(')
				lparenth++;
			if(c==')')
				rparenth++;
			break;
		case 1:
			printf("Error 4! '+','-','*','/','.' cannot be put together or at the very end or before ')'.\n");// Error 4
			ismistake=1;
			goto end;
		case 2:
			printf("Error 5! '(' cannot be put at last or followed by ')','*','/','.'.\n");// Error 5
			ismistake=1;
			goto end;
		case 3:
			printf("Error 6! ')' cannot be followed by numbers and '('.\n");// Error 6
			ismistake=1;
			goto end;
		case 4:
			printf("Error 7! Numbers cannot be followed by '('.\n");// Error 7
			ismistake=1;
			goto end;
		}
		sign1=sign2;
	}
	if(lparenth!=rparenth)
	{
		ismistake=1;
		printf("Error 8! The parenthesis are not matched\n");
	}// Error 8
end:
	if(ismistake==1)
		printf("Error occurred! You should input arithmetic expression again!\n");
}

double evaluate()					//计算表达式的值
{
	double a,b,gd,tempresult;
	char c,symbol,gt,temp[20];
	int i=0,isfigure=0,issigned=0;
	int j=0;
	double number;
	pushoprt('\0');
	c=expression[0];
	if(c=='+')c=expression[i++];
	if(c=='-')pushopnd(0);
	gt=getoprt();
	while(c!='\0'||gt!='\0')
	{
		if(c>='0'&&c<='9'||c=='.')
		{
			isfigure=1;issigned=0;
			temp[j++]=c;
			c=expression[++i];
		}
		else 
		{
			if(isfigure==1){temp[j]='\0';number=dtod(temp);pushopnd(number);}
			isfigure=0;j=0;
			if(c=='(')issigned=1;
			if(c=='-'&&issigned==1)pushopnd(0);
			if(c=='+'&&issigned==1)i++;
			gt=getoprt();
			switch(priority(gt,c))
			{
			case'<':
				{pushoprt(c);c=expression[++i];break;}
			case'=':
				{symbol=popoprt();c=expression[++i];break;}
			case'>':
				{symbol=popoprt();b=popopnd();a=popopnd();
				tempresult=calculate(a,symbol,b);
				pushopnd(tempresult);break;}
			}
		}
		gt=getoprt();
	}
	gd=getopnd();
	return(gd);
}

void menu()
{
	printf("  *****************************************************************\n");
	printf("  *                          Command Menu                         *\n");
	printf("  *  1. Command Menu                                   [menu]     *\n");
	printf("  *  2. Expression Evaluation                          [run]      *\n");
	printf("  *  3. Number Base Conversion                         [convert]  *\n");
	printf("  *  4. Quit this program                              [quit]     *\n");
	printf("  *  5. Clear the screen                               [cls]      *\n");
	printf("  *                                                               *\n");
	printf("  *****************************************************************\n");
}

void quit()
{
	printf("******************************************************\n");
	printf("**             Thanks for using my program!         **\n");
	printf("**  I wrote this program just for my DS homework.:) **\n");
	printf("**  There might be some errors and bugs in my code. **\n");
	printf("**  If you have any problems,                       **\n");
	printf("**     write to phoenixinter@126.com                **\n");
	printf("**  Or contact me by QQ:50147231                    **\n");
	printf("**                ^_^ Bye for now~                  **\n");
	printf("******************************************************\n");
}

void run()
{
	double result;
loop:
	initexpression();
	check();
	if(ismistake==0)
	{
		result=evaluate();
		printf("VALUE = %f\n",result);
	}
	else
	{
		ismistake=0;
		goto loop;
	}
}

void main()
{
	char k,key[8];
loop1:
	menu();
	printf("Your Command:");
	scanf(" %s",key);
	while(strcmp(key,"run")!=0)
	{
		if(strcmp(key,"menu")==0)
			menu();
		else if(strcmp(key,"convert")==0)
			convert();
		else if(strcmp(key,"cls")==0)
			system("cls");
		else if(strcmp(key,"quit")==0)
		{
			quit();
			exit(0);
		}
		else
			printf("Wrong Command!\n");
		printf("Your Command:");
		scanf(" %s",key);
	}
loop2:
	run();
	printf("Continue to calculate or back to command menu?\n");
	printf("Continue--->'C',Back--->B (C/B)?");
loop3:
	scanf(" %c",&k);
	if(k=='c'||k=='C')
	{
		ismistake=0;
		goto loop2;
	}
	else if(k=='b'||k=='B')
		goto loop1;
	else
	{
		printf("Wrong Command!\nInput again(C/B)?"); 
		goto loop3;
	}
}

void convert()
{
	int choice;
	char k;
	double dec;
	float deci;
loop1:
	printf("  *****************************************************************\n");
	printf("  *                          Convert Menu                         *\n");
	printf("  *          <Binary>                          <Octal>            *\n");
	printf("  *  [1]. binary to octal            [4]. octal to binary         *\n");
	printf("  *  [2]. binary to decimal          [5]. octal to decimal        *\n");
	printf("  *  [3]. binary to hexadecimal      [6]. octal to hexadecimal    *\n");
	printf("  *                                                               *\n");
	printf("  *          <Decimal>                       <Hexadecimal>        *\n");
	printf("  *  [7]. decimal to binary          [10].hexadecimal to binary   *\n");
	printf("  *  [8]. decimal to octal           [11].hexadecimal to octal    *\n");
	printf("  *  [9]. decimal to hexadecimal     [12].hexadecimal to decimal  *\n");
	printf("  *                                                               *\n");
	printf("  *****************************************************************\n");
	printf("Please enter your choice:[  ]\b\b\b");
loop2:
	scanf(" %d",&choice);
	if(choice>0&&choice<13);
	else
	{
		printf("Invalid choice! choose again:[  ]\b\b\b");
		goto loop2;
	}
loop3:
	switch(choice)
	{
	case  1:btod();dtoo(chiaus);break;
	case  2:btod();break;
	case  3:btod();dtoh(chiaus);break;
	case  4:otod();dtob(chiaus);break;
	case  5:otod();break;
	case  6:otod();dtoh(chiaus);break;
	case  7:printf("Please input a decimal:");scanf(" %f",&deci);dec=(double)deci;dtob(dec);break;
	case  8:printf("Please input a decimal:");scanf(" %f",&deci);dec=(double)deci;dtoo(dec);break;
	case  9:printf("Please input a decimal:");scanf(" %f",&deci);dec=(double)deci;dtoh(dec);break;
	case 10:htod();dtob(chiaus);break;
	case 11:htod();dtoo(chiaus);break;
	case 12:htod();break;
	}
	printf("Continue to convert or Select a new mode or Back to command menu?\n");
	printf("Continue--->C,Select--->S,Back--->B (C/S/B)?");
loop4:
	scanf(" %c",&k);
	if(k=='c'||k=='C')
		goto loop3;
	else if(k=='b'||k=='B')
		main();
	else if(k=='s'||k=='S')
		goto loop1;
	else
		printf("Wrong Command!\nInput again(C/S/B)?");
	goto loop4;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -