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

📄 arithmetic.c

📁 本程序是用纯C语言编的一个基于命令行的四则运算计算器。主要用于计算四则运算表达式的值
💻 C
字号:
/*****************************************************************************
 * 本程序是用纯C语言编的一个基于命令行的四则运算计算器。主要用于计算四则运算
 * 表达式的值,同时可以实现四种进制任意两种之间的转换。
 * 主要功能:1.四则运算:能够解释并执行四则运算表达式。
 * 四则运算就是包含+、—、*、/、.(小数点)和数字的运算表达式,
 * 例如:3+2.9*(5-6/3) -4+(+8*6)等;	
 * 2.错误警告:能够对不符合语法的表达式给出相应的错误警告,本程序共给出了8大类警告
 * 3.进制转换:能够做二进制、八进制、十进制、十六进制中任意两种进制之间的互相转换
 * 4.帮助系统:提供完善的帮助系统;
 * 5.出错保护:要有良好的出错保护系统,命令行输入错误,程序仍能正常运行。
 *  Author: Edward Lee
 *  Date:  08/2002
 *  Contact: edward.li@163.com
 ****************************************************************************/

#include"stdio.h"
#include"string.h"
#include"stdlib.h"
#define STACKSIZE 100
int topt=-1;
int topd=-1;
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("Operend Stack overflow!\n");
	opnd[++topd]=x;
}

void pushoprt(char x)
{
	if(topt==STACKSIZE-1) printf("Operate Stack overflow!\n");
	oprt[++topt]=x;
}

double popopnd()
{
	if(topd==-1) printf("Operend Stack underflow!\n");
	return(opnd[topd--]);
}

char popoprt()
{
	if(topt==-1) printf("Operate Stack underflow!\n");
	return(oprt[topt--]);
}

double getopnd()
{
	if(topd==-1) printf("Operend Stack underflow!\n");
	return(opnd[topd]);
}

char getoprt()
{
	if(topt==-1) printf("Operate Stack underflow!\n");
	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 arithmetic expression, never input a space or a tab.\n");
	printf("Press Enter button to end 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]='b';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]='b';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]='b';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 last 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("You should input arithmetic expression again!\n");
}

double evaluate(void)
{
	double a,b,gd,tempresult;//value,
	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. to open Command menu                           [menu]     *\n");
	printf("  *  2. to calculate value of arithmetic expression    [run]      *\n");
	printf("  *  3. to learn more details about this program       [more]     *\n");
	printf("  *  4. to quit this program                           [quit]     *\n");
	printf("  *  5. to clean the screen                            [clean]    *\n");
	printf("  *  6. to convert number base(default:decimal)        [convert]  *\n");
	printf("  *  7. to learn how to use the program                [help]     *\n");
	printf("  *                                                               *\n");
	printf("  *****************************************************************\n");
}

void thanks()
{
	printf("   *=================Thanks for using my program!================*\n");
	printf("   *     If you have some suggestions, just contact with me.     *\n");
	printf("   *                 telephone : 00000000                        *\n");
	printf("   *                 QQ : 27512609                               *\n");
	printf("   *                 e-mail : edward.li@163.com                  *\n");
	printf("   *==================My sincere thanks to you!==================*\n");
}

void help()
{
	system("type help.txt | more");
}

void run()
{
	double result;
loop:
	initexpression();
	check();
	if(ismistake==0)
	{
		result=evaluate();
		printf("=========================\n");
		printf("*  value = %e  *\n",result);
		printf("=========================\n");
	}
	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,"help")==0) help();
		else if(strcmp(key,"more")==0) system("type arithmetic.txt | more");
		else if(strcmp(key,"convert")==0)convert();
		else if(strcmp(key,"clean")==0)system("cls");
		else if(strcmp(key,"quit")==0) {thanks();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");
loop2:
	scanf(" %d",&choice);
	if(choice>0&&choice<13);
	else {printf("Invalid choice! choose again:[ ]\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 + -