本程序可以对 “输入的表达式” 和 “从文件里面读入的表达式” 进行运算
并且支持对负号的处理

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

#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_SIZE 10     //栈的总存储容量
#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语言实现科学计算器的加减乘除平方开放运算相关推荐

  1. linux 计算器 c语言,大神教你如何用C语言实现科学计算器

    原标题:大神教你如何用C语言实现科学计算器 用C实现的科学计算器 使用C语言写的科学计算器,可以实现四则运算.三角函数运算.指对数运算:优先级正确:能智能屏蔽空格,能识别输入错误和运算错误,能实现继续 ...

  2. Qt 做个简易的计算器,加减乘除平方开根

    这个小项目主要练习qt的控件布局,就只用两个控件就可以做出来了,pushButton和textEdit这两个控件,当然你想搞个标准计算器和科学计算器的话,也可以加个tabWidget或者ToolBox ...

  3. c语言编程计算器开平方,用c语言实现科学计算器要求有计算器界面 可以加减乘除平方开方...

    满意答案 LADYgemen 2019.07.02 采纳率:58%    等级:9 已帮助:568人 #include "stdafx.h" #define STACK_INIT_ ...

  4. c语言设计简单计算器,c语言设计简单计算器实现加减乘除运算

    编写程序的目的就是使程序有他应用的地方,编写一个简单的计算器来实现我们计算的目的. 利用swich  case 语句和循环结构来实现简单程序的编写.利用选择语句来进行输入的选择,然后利用所输入的数字的 ...

  5. C语言科学计算器思路,大神教你如何用C语言实现科学计算器

    i++; *len=i; return temp; } /*功能:翻译操作数 * 如果运算符非法,则返回0,合法则返回非零标志 */ int translateopt(char *p,int *len ...

  6. c语言程序算法思想,C语言实现科学计算器(算法思想)

    程序设计目的是用户可以输入中缀表达式,回车后计算出结果. 首先要知道中缀表达式如何转换成后缀(前缀)表达式,中缀表达式是人容易理解的表达式,而对计算机来说,计算中缀表达式是很困难的.所以我们先把中缀表 ...

  7. C语言实现科学计算器

    如不清楚算法思路,请点下方的链接: 算法思路 #include<stdio.h> #include<stdlib.h>/*数据栈*/ struct shuju {int dat ...

  8. 用栈实现计算器c语言报告,请问,用c语言做一个计算器 包括+-*/()的运算 用栈 该怎么做...

    该楼层疑似违规已被系统折叠 隐藏此楼查看此楼 #include #include #define UINT unsigned int struct LOGIC { UINT logic,site; } ...

  9. c语言用栈实现计算器加法运算,请问,用c语言做一个计算器 包括+-*/()的运算 用栈 该怎么做...

    该楼层疑似违规已被系统折叠 隐藏此楼查看此楼 #include #include #define UINT unsigned int struct LOGIC { UINT logic,site; } ...

最新文章

  1. 深入理解JVM(二)--垃圾收集算法
  2. 美国计划让“人工智能”去搜寻外星人!
  3. 程序员的“凡尔赛文学”大赏!
  4. linux 卸载模块命令,Linux中module模块的编译、加载、卸载
  5. python爬虫系列之数据的存储(二):csv库的使用
  6. MySQL explain 命令
  7. myeclipse8.5打包jar并引入第三方jar包
  8. java 反射 接口_Java 怎么通过反射获取并实现这个类里面的接口,并且实现接口中的方法...
  9. RoadRunner安装与使用教程
  10. UE4 C++ Base64编解码
  11. 什么是COM组件以及怎样创建(C#)?
  12. [渝粤教育] 中国地质大学 信息检索 复习题 (2)
  13. 每秒浮点运算次数FLOPS
  14. 【Python基础】初识-与君初相识,犹如故人归
  15. 陈强教授 计量经济学及机器学习等数据集、程序等相关资源
  16. 利用BLAST进行序列比对和寻找同源基因
  17. 匿名邮件爆迅雷看看丑闻
  18. Java集合原理分析
  19. 中兴路由器,交换机DHCP原理,dhcp配置,实例
  20. Linux单机到Windows的OGG安装部署步骤

热门文章

  1. 熟悉Android---使用imageView加载网络图片
  2. 哪里有比Excel还好用的在线表单制作工具?
  3. php5ts崩溃,热门问题 浏览器崩溃原因与解决办法? | 傲游5云浏览器常见问题...
  4. android判断特殊字符,如何判断一个特殊字符是英文的还是中文的?
  5. Oracle实施方法——PJM/AIM
  6. Blender2.9-keymap
  7. STM32模拟I2C协议获取MLX90615红外温度传感器测温数据(Open Drain管脚配置)
  8. 关于千兆以太网项目的补充:FCS、CRC等校验功能
  9. 1001 Motivational Quotes for Success by Thomas J. Vilord
  10. 【愚公系列】2023年06月 网络安全(交通银行杯)-数据包里有甜甜圈哦~