失眠网,内容丰富有趣,生活中的好帮手!
失眠网 > C语言实现科学计算器的加减乘除平方开放运算

C语言实现科学计算器的加减乘除平方开放运算

时间:2020-08-14 04:06:17

相关推荐

C语言实现科学计算器的加减乘除平方开放运算

本程序可以对 “输入的表达式” 和 “从文件里面读入的表达式” 进行运算

并且支持对负号的处理

代码运行时有一个警告信息 ,但是不影响运行和最终的结果。不知道问题出在哪!

#define _CRT_SECURE_NO_WARNINGS#include<stdio.h>#include<stdlib.h>#include<ctype.h>#include<math.h>#include<string.h>#include<iostream>using namespace std;typedef double ElemType;typedef char ElemType_c;#define STACK_INIT_SIZE10//栈的总存储容量#define STACKINCREMENT 10 //增加的容量#define MAXBUFFER 10 //字符串的长度typedef struct SqStack//ElemType类型的栈{ElemType *base;//栈底指针ElemType *top;//栈顶指针int stacksize;//栈总的可用容量}SqStack;typedef struct SqStack_c{ElemType_c *base;ElemType_c *top;int stacksize;}SqStack_c;struct Cal_Return{double Retur;int flag = 1;};//栈的建立SqStack* InitStack(){SqStack *s = (SqStack *)malloc(sizeof(SqStack));s->base = (ElemType *)malloc(STACK_INIT_SIZE * sizeof(ElemType));if (!s->base)exit(0);s->top = s->base;s->stacksize = STACK_INIT_SIZE;return s;}SqStack_c* InitStack_c(){SqStack_c *s = (SqStack_c *)malloc(sizeof(SqStack_c));s->base = (ElemType_c *)malloc(STACK_INIT_SIZE * sizeof(ElemType_c));if (!s->base)exit(0);s->top = s->base;s->stacksize = STACK_INIT_SIZE;return s;}//压栈bool Push(SqStack *s, ElemType e){if (s->top - s->base >= s->stacksize){s->base = (ElemType *)realloc(s->base, (s->stacksize + STACKINCREMENT) * sizeof(ElemType)); //如果栈满了,扩充栈容量if (!s->base)return false;s->top = s->base + s->stacksize;s->stacksize = s->stacksize + STACKINCREMENT;}*(s->top) = e;s->top++;return true;}bool Push_c(SqStack_c *s, ElemType_c e){if (s->top - s->base >= s->stacksize){s->base = (ElemType_c *)realloc(s->base, (s->stacksize + STACKINCREMENT) * sizeof(ElemType_c)); //如果栈满了,扩充栈容量if (!s->base)return false;s->top = s->base + s->stacksize;s->stacksize = s->stacksize + STACKINCREMENT;}*(s->top) = e;s->top++;return true;}//出栈bool Pop(SqStack *s, ElemType &e){if (s->top == s->base)return false;--(s->top);e = *(s->top);return true;}bool Pop_c(SqStack_c *s, ElemType_c &e){if (s->top == s->base)return false;--(s->top);e = *(s->top);return true;}//获取栈顶元素,不出栈ElemType GetTop(SqStack *s){ElemType e;if (s->top == s->base)exit(0);e = *(s->top - 1);return e;}ElemType_c GetTop_c(SqStack_c *s){ElemType_c e;if (s->top == s->base)exit(0);e = *(s->top - 1);return e;}//清空栈void ClearStack(SqStack *s){s->top = s->base;}void ClearStack_c(SqStack_c *s){s->top = s->base;}//销毁一个栈void DestroyStack(SqStack *s){//int ll;//ll = s->stacksize;if (s->base)free(s->base);s->base = s->top = NULL;s->stacksize = 0;free(s);s = NULL;}void DestroyStack_c(SqStack_c *s){//int len;//len = s->stacksize;if (s->base)free(s->base);s->base = s->top = NULL;s->stacksize = 0;free(s);s = NULL;}//计算栈的当前大小int StackLen(SqStack *s){return(s->top - s->base);}int StackLen_c(SqStack_c *s){return(s->top - s->base);}//显示栈内元素void DisplayStack(SqStack*s){int length;ElemType *initbase = s->base;length = (s->top - s->base);for (int i = 0; i < length; i++){cout << *(s->base) << " ";s->base++;}cout << endl;s->base = initbase;}void DisplayStack_c(SqStack_c* s){int length;ElemType_c *initbase = s->base;length = (s->top - s->base);for (int i = 0; i < length; i++){cout << *(s->base) << " ";s->base++;}cout << endl;s->base = initbase;}//处理负数问题 char Minus(char *ss,char *AA){int ll=strlen(ss),len=0,i=0;while(i<ll){if (ss[i]=='-' && (i==0 || ss[i-1]=='+' || ss[i-1]=='-' || ss[i-1]=='*'|| ss[i-1]=='/' || (ss[i-1]=='(' && ss[i-2] != '@') )){AA[len++]='(';AA[len++]='0';AA[len++]='-';i++;AA[len++]=ss[i++];AA[len++]=')';}else if(ss[i] == '-' && ss[i-1] == '@'){//负数不能进行开方printf("Error Input : Squart-root Can not be negative number\n");exit(0);}else if(ss[i] == '-' && ss[i-1] == '(' && ss[i-2] == '@'){//负数不能进行开方printf("Error Input : Squart-root Can not be negative number\n");exit(0);}else AA[len++]=ss[i++];}AA[len]='\0';//printf("%s\n",AA);//处理了负数后的表达式 return *AA;}//中缀表达式变后缀表达式 char nibolan(SqStack_c *C ,char *AA , char *vect){//2、将中缀表达式转换为后缀表达式//将(2) 里面的printf打开 可以输出转换后的后缀表达式//printf("转换后的后缀表达式为: \n");int i=0;int j = 0;char e;while (AA[i] != '='){while (isdigit(AA[i]) || AA[i] == '.')//如果输入的是数字或者小数点,则直接输出,如果是连续输入的数或小数点,则中间无空格{//printf("%c", AA[i]);vect[j++] = AA[i];vect[j] = '\0';i++;if (!(isdigit(AA[i]) || AA[i] == '.')){printf(" ");vect[j++] = ' ';vect[j] = '\0';}}if (AA[i] == ')') //如果输入是右括号,则出栈一直到左括号{Pop_c(C, e);while (e != '(') {//printf("%c ", e);vect[j++] = e;vect[j++] = ' ';vect[j] = '\0';Pop_c(C, e);}}else if (AA[i] == '+' || AA[i] == '-')//如果输入是加号或减号,则先判断优先级{if (!StackLen_c(C))//如果栈空,则直接入栈Push_c(C, AA[i]);else//如果非空,先弹栈{do {Pop_c(C, e);if (e == '(')//如果弹出来的是左括号,则直接将c入栈Push_c(C, e);else //如果弹出来的不是左括号,则出栈直到栈空或遇到左括号,再将c入栈{//printf("%c ", e);vect[j++] = e;vect[j++] = ' ';vect[j] = '\0';}} while (e != '(' && StackLen_c(C));Push_c(C, AA[i]);}}else if (AA[i] == '*' || AA[i] == '/' ) //如果输入的是*或者/ 则判断优先级{if (!StackLen_c(C))//如果栈空,则直接入栈Push_c(C, AA[i]);else//如果非空,先弹栈{do {Pop_c(C, e);if (e == '+' || e == '-' || e == '(')//如果弹出来的是左括号或者加号或者减号,则直接将c入栈Push_c(C, e);else //如果弹出来的不是左括号,则出栈直到栈空或遇到左括号,再将c入栈{printf("%c ", e);vect[j++] = e;vect[j++] = ' ';vect[j] = '\0';}} while (e != '(' && e!='+' && e!='-' && StackLen_c(C)); //如果弹出来的不是左括号加号或者减号,则出栈直到栈空或遇到左括号,再将c入栈Push_c(C, AA[i]);}}else if(AA[i] == '^' || AA[i] == '@' || AA[i] == '(')//如果输入的是开方或者求幂符号 ;Push_c(C,AA[i]);else if (AA[i] == '=')//如果输入是 “= ”,结束break;else{printf("输入表达式错误,请检查输入 \n");break;}i++;}//最后栈不为空的话,栈中元素全部弹出while (StackLen_c(C)){Pop_c(C, e);//printf("%c ", e);vect[j++] = e;vect[j++] = ' ';vect[j] = '\0';}vect[j - 1] = '=';return *AA;return *vect;} //1 、封装用栈实现后缀表达式的计算的calc_1函数 用于手动输入的表达式进行计算 int calc_1(char *vect,char*ss){SqStack *s = InitStack();//初始化一个栈double d, f;char g;int m = 0;int k = 0;char str[MAXBUFFER];g = vect[k++];while (g != '='){while (isdigit(g) || g == '.') //判断输入的字符是不是十进制数或小数点{//把同一个数存储到一个字符串中str[m++] = g;str[m] = '\0';if (m >= MAXBUFFER){printf("出错:输入的单个数据过大 \n");return -1;}g = vect[k++];if (g == ' ')//必须在数字后面的空格=才会生效{d = atof(str);//字符串转double类型函数Push(s, d);m = 0;break;}}switch (g){case '+':Pop(s, f);Pop(s, d);Push(s, d + f);break;case '-':Pop(s, f);Pop(s, d);Push(s, d - f);break;case '*':Pop(s, f);Pop(s, d);Push(s, d*f);break;case '^':Pop(s,f);Pop(s,d);Push(s,pow(d,f));break;case '@':Pop(s,f);Push(s,sqrt(f));break;case '/': //分母不能为0 Pop(s, f);Pop(s, d);if(f != 0){Push(s, d / f);}else {Push(s,1);printf("Error Input,divide 0\n");//exit(0);break;}break;}g = vect[k++];}Pop(s, d);printf("\n最终结果为:%s%f\n\n", ss,d);printf("请输入您的选择\n1:输入表达式\n2:文件计算\n");}//2 、封装用栈实现后缀表达式的计算的calc_2函数 用于文件输入的表达式进行计算Cal_Return calc_2(char *vect,char*ss){Cal_Return total;SqStack *s = InitStack();//初始化一个栈double d, f;char g;int m = 0;int k = 0;char str[MAXBUFFER];g = vect[k++];while (g != '='){while (isdigit(g) || g == '.') //判断输入的字符是不是十进制数或小数点{//把同一个数存储到一个字符串中str[m++] = g;str[m] = '\0';if (m >= MAXBUFFER){printf("出错:输入的单个数据过大 \n");exit(0);//return -1;}g = vect[k++];if (g == ' ')//必须在数字后面的空格=才会生效{d = atof(str);//字符串转double类型函数Push(s, d);m = 0;break;}}switch (g){case '+':Pop(s, f);Pop(s, d);Push(s, d + f);break;case '-':Pop(s, f);Pop(s, d);Push(s, d - f);break;case '*':Pop(s, f);Pop(s, d);Push(s, d*f);break;case '^':Pop(s,f);Pop(s,d);Push(s,pow(d,f));break;case '@':Pop(s,f);Push(s,sqrt(f));break;case '/': //分母不能为0 Pop(s, f);Pop(s, d);if(f != 0){total.flag = 1;Push(s, d / f);}else {total.flag = 0;Push(s,1);//printf("Error Input In File, divide 0\n");//exit(0);break;}break;}g = vect[k++];}Pop(s, d);total.Retur = d;return total;printf("\n最终结果为:%s%f\n\n", ss,d);printf("请输入您的选择\n1:输入表达式\n2:文件计算\n");}int main(){int Select;printf("欢迎使用计算器:该计算器支持加(+)、减(-)、乘(*)、除(/)、求幂(^)、开方(@)运算\n\n");printf("请输入您的选择\n 1:输入表达式\n 2:文件计算\n 666:退出程序\n\n");while(~scanf("%d", &Select)){getchar(); //把输入的 \n 给读掉; if(Select == 1){SqStack_c *C = InitStack_c();char ss[50],AA[50];char vect[50]; //将输出的后缀表达式存在字符串中,以备计算后缀表达式使用printf("请输入算数表达式(中缀表达式),以=作为结束标志\n"); printf("例如1+2=\n");gets(ss); //读入整行Minus(ss,AA); nibolan(C, AA,vect);calc_1(vect,ss); //调用calc函数 }else if(Select == 666) exit(0); else if (Select == 2){char Inp[] = "Error Input In File, divide 0";FILE * pFile;FILE * fp2;char mystring [100];char* res[999]; //store final resultint p=0; //pointer of res[]pFile = fopen ("input.txt" , "r");fp2 = fopen("output.txt" , "w");if (pFile == NULL)perror ("Error opening file");else{while ( fgets (mystring , 100 , pFile) != NULL ) //每次读入一行 {int len = strlen(mystring);if(mystring[len-1]=='\n') mystring[len-1] = '\0'; //定义结尾 char* tmp = (char*)malloc(100*sizeof(char));SqStack_c *C = InitStack_c();char AA[50],ss[50];char vect[50];double Res; memcpy(tmp,mystring,len); // 内存拷贝 fputs(tmp,fp2); //将表达式输入到output.txt里面 strncpy(ss,tmp,20);//将tmp里面的内容拷贝到ss里面 方便后面进行计算 Minus(ss,AA); nibolan(C, AA,vect); //double Answer = calc_2(vect,ss,Res); //调用calc函数 并用double类型的 Answer接受结果;Cal_Return File_Ret_1 = calc_2(vect,ss);if(File_Ret_1.flag == 1){char abc[20]; sprintf(abc,"%.5lf",File_Ret_1.Retur);//将double类型转变成char类型 fputs(abc,fp2); //将结果输入到 output.txt文件里面 fputs("\n",fp2);}else if (File_Ret_1.flag == 0){fputs(Inp,fp2); //将结果输入到 output.txt文件里面 fputs("\n",fp2);}res[p++] = tmp;DestroyStack_c(C);}printf("\n");printf("已对输入文件里面的运算表达式进行了计算,结果放在output.txt文件里面\n");fclose (pFile);fclose(fp2);}} else printf("选择错误,请重新选择(输入可666退出该程序)\n");}system("pause");return 0;}

如果觉得《C语言实现科学计算器的加减乘除平方开放运算》对你有帮助,请点赞、收藏,并留下你的观点哦!

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。