基于c的简易计算器二

  1 #include <stdio.h>
  2 #include <string.h>
  3 #include <stdlib.h>
  4 #include <ctype.h>
  5 #include <math.h>
  6 #include <stdbool.h>
  7 #include <malloc.h>
  8 
  9 #define STACK_SIZE 100
 10 #define APPEND_SIZE 10
 11 
 12 struct SNode
 13 {
 14     double data;    //存放操作数或者计算结果
 15     char ch;       //存放运算符
 16 };
 17 struct Stack       //顺序栈,用于计算表达式
 18 {
 19     struct SNode *top;
 20     struct SNode *base;
 21     int size;
 22 };
 23 
 24 int InitStack(struct Stack *S);           //初始化栈
 25 int DestroyStack(struct Stack *S);        //销毁栈
 26 int ClearStack(struct Stack *S);          //清空栈
 27 int GetTop(struct Stack S, struct SNode *Elem);  //取出栈顶结点并返回节点值
 28 int Push(struct Stack *S, struct SNode Elem);    //入栈
 29 int Pop(struct Stack *S, struct SNode *Elem);    //出栈
 30 
 31 
 32 
 33 void OutPut(char *pFormula, double CurrentNum, int Mflg);//主循环格式输出
 34 int RtOpe(char **pKey, char *pIn);                   //判断操作符以及计算器功能
 35 double Cal(char *pFormula);                              //计算表达式
 36 int Check(char *pFormula);                               //检查表达式
 37 
 38 char Judge(struct SNode Popc, struct SNode Cr);//比较运算符优先级
 39 double Operate(double Numa, char Opr, double Numb);//计算a,b经过opr运算后的结果
 40 char *killzero(char *Str, double Result);//消除末尾的0
 41 
 42 int main(void)
 43 {
 44     char Formula[100]={'\0'};
 45     char *pFormula=Formula;
 46     char In[20];
 47 
 48     int M=0,Mflg=0;
 49     char *Key[17]={"+","-","*","/","=","MC","MR","MS","M+","M-","CE","C","~","sqr","rec","(",")"};
 50     char **pKey=Key;
 51     double CurrentNum =0;
 52     bool fg=false;
 53 
 54     OutPut(pFormula , CurrentNum, Mflg);
 55     while (1)
 56     {
 57         scanf("%s", In);
 58         if(isdigit(In[0]) != 0)//当前输入的是数字
 59         {
 60             CurrentNum=atof(In);
 61             if(false == fg)
 62             {
 63                 strcat(pFormula, In);
 64             }
 65             fg=false;
 66         }
 67         else                 //当前输入的是操作符
 68         {
 69             switch(RtOpe(pKey, In))//判断是什么操作符
 70             {
 71             case 0://"+"   写入算式
 72                 {
 73                     strcat(pFormula, In);
 74                     fg=false;
 75                     break;
 76                 }
 77             case 1://"-"   写入算式
 78                 {
 79                     strcat(pFormula, In);
 80                     fg=false;
 81                     break;
 82                 }
 83             case 2://"*"   写入算式
 84                 {
 85                     strcat(pFormula, In);
 86                     fg=false;
 87                     break;
 88                 }
 89             case 3://"/"   写入算式
 90                 {
 91                     strcat(pFormula, In);
 92                     fg=false;
 93                     break;
 94                 }
 95             case 4://"="   计算算式的值
 96                 {
 97                     CurrentNum=Cal(pFormula);
 98                     fg=false;
 99                     break;
100                 }
101             case 5://"MC"  清除存储器中的值
102                 {
103                     M=0;
104                     Mflg=0;
105                     fg=false;
106                     break;
107                 }
108             case 6://"MR"  显示存储器中的值
109                 {
110                     CurrentNum=M;
111                     fg=false;
112                     break;
113                 }
114             case 7://"MS"  将当前的值存放到存储器中
115                 {
116                     M=CurrentNum;
117                     Mflg=1;
118                     fg=true;
119                     break;
120                 }
121             case 8://"M+"  将当前值和存储器中的值相加并存储
122                 {
123                     M+=CurrentNum;
124                     fg=false;
125                     break;
126                 }
127             case 9://"M-"  将存储器中的值减去当前值并存储
128                 {
129                     M-=CurrentNum;
130                     fg=false;
131                     break;
132                 }
133             case 10://"CE" 清除显示的数字
134                 {
135                     CurrentNum=0;
136                     fg=false;
137                     break;
138                 }
139             case 11://"C"  归零,清除当前的计算
140                 {
141                     CurrentNum=0;
142                     Formula[0]='\0';
143                     fg=false;
144                     break;
145                 }
146             case 12://"~"改变当前值的正负
147                 {
148                     CurrentNum=0-CurrentNum;
149                     fg=false;
150                     break;
151                 }
152             case 13://"sqr"求当前值的平方根
153                 {
154                     if(CurrentNum >= 0)
155                     {
156                         CurrentNum=sqrt(CurrentNum);
157                     }
158                     else
159                     {
160                         printf("\nError Calculate !\n");
161                     }
162                     fg=false;
163                     break;
164                 }
165             case 14://"rec"求显示数字的1/x的值
166                 {
167                     if(CurrentNum != 0)
168                     {
169                         CurrentNum=1/CurrentNum;
170                     }
171                     else
172                     {
173                         printf("\nError Calculate !\n");
174                     }
175                     fg=false;
176                     break;
177                 }
178             case 15://"("   写入算式
179                 {
180                     strcat(pFormula, In);
181                     fg=false;
182                     break;
183                 }
184             case 16://")"   写入算式
185                 {
186                     strcat(pFormula, In);
187                     fg=false;
188                     break;
189                 }
190             default:printf("\nError input !\n");
191                     fg=false;
192                     break;
193             }
194         }
195         OutPut(pFormula, CurrentNum, Mflg);
196     }
197     return 0;
198 }
199 
200 void OutPut(char *pFormula, double CurrentNum, int Mflg)//主循环格式输出
201 {
202     system("cls");
203     int i=0;
204     char Str[50];
205     char *pStr=Str;
206     double num=CurrentNum;
207     if(num >= 999999999999999)
208     {
209         num=999999999999999;
210     }
211     printf("\n");
212 
213     while (*(pFormula+i) != '\0')
214     {
215         printf("%c", *(pFormula+i));
216         i++;
217     }
218     printf("\n");
219     if(Mflg == 1)
220     {
221         printf("M");
222     }
223     printf("\t%s\n", killzero(pStr, num));
224     printf("\nMC\tMR\tMS\tM+\tM-\tCE\tC\t~\tsqr\trec\t(\t)\ninput:");
225 
226 }
227 
228 int RtOpe(char **pKey, char *pIn)//判断输入的操作符或者功能
229 {
230     int i;
231     for(i=0; i<17; i++)
232     {
233         if(strcmp(pKey[i], pIn) == 0)
234         {
235             return i;
236         }
237     }
238     return -1;
239 }
240 
241 
242 int Check(char *pFormula)//判断表达式是否合格
243 {
244     int i=0;
245     int flag=0;
246     while(*(pFormula+i) != '\0')
247     {
248         if((*(pFormula+i) >= '0' && *(pFormula+i) <= '9') || *(pFormula+i) == '+' || *(pFormula+i) == '-'
249                 || *(pFormula+i) == '*' || *(pFormula+i) == '/' || *(pFormula+i) == '('
250                 || *(pFormula+i) == ')' || *(pFormula+i) == '.')
251         {
252             if(*(pFormula+i) == '(')
253             {
254                 flag++;
255             }
256             else if(*(pFormula+i) == ')')
257             {
258                 flag--;
259             }
260         }
261         else
262         {
263             printf("\nError formula !\n");
264             return 0;
265         }
266         i++;
267     }
268     if(flag != 0)
269     {
270         printf("\nthe number '(',')' is wrong !\n");
271         return 0;
272     }
273     else
274     {
275         return 1;
276     }
277 }
278 
279 int InitStack(struct Stack *S)//初始化栈
280 {
281     S->base=(struct SNode *)malloc(STACK_SIZE * sizeof(struct SNode));
282     if(S->base == NULL)
283     {
284         printf("\nMemory allocation failure !\n");
285         return -1;
286     }
287     S->top=S->base;
288     S->size=STACK_SIZE;
289     return 0;
290 }
291 
292 int DestroyStack(struct Stack *S)//销毁栈
293 {
294     free(S->base);
295     return 0;
296 }
297 
298 int ClearStack(struct Stack *S)//清除栈
299 {
300     S->top=S->base;
301     return 0;
302 }
303 
304 int GetTop(struct Stack S, struct SNode *Elem)//取出栈顶结点并返回节点值
305 {
306     if(S.top == S.base)
307     {
308         printf("Stack is empty !");
309         return -1;
310     }
311     *Elem=*(S.top-1);
312     return 0;
313 }
314 
315 int Push(struct Stack *S, struct SNode Elem)//入栈
316 {
317     if(((S->top)-(S->base)) >= S->size)
318     {
319         S->base=(struct SNode *)realloc(S->base,(S->size+APPEND_SIZE)*sizeof(struct SNode));
320         if(S->base == NULL)
321         {
322             printf("Memory allocation failure !");
323             return -1;
324         }
325         S->top=S->base+S->size;
326         S->size+=APPEND_SIZE;
327     }
328     *(S->top)=Elem;
329     S->top++;
330     return 0;
331 }
332 
333 int Pop(struct Stack *S, struct SNode *Elem)//出栈
334 {
335     if(S->top == S->base)
336     {
337         printf("Stack is empty !");
338         return -1;
339     }
340     *Elem=*(S->top-1);
341     S->top--;
342     return 0;
343 }
344 
345 
346 double Operate(double Numa, char Opr, double Numb)//计算Numa,Numb经过Opr运算后的结果
347 {
348     switch(Opr)
349     {
350         case '+':
351             return (Numa+Numb);
352         case '-':
353             return (Numa-Numb);
354         case '*':
355             return (Numa*Numb);
356         case '/':
357         {
358             if(Numb != 0)
359             {
360                 return (Numa/Numb);
361             }
362             else
363             {
364                 printf("\nDivide by zero !\n");
365             }
366         }
367         default :
368             return 0;
369     }
370 }
371 
372 char Judge(struct SNode Popc, struct SNode Cr)//比较操作符优先级
373 {
374     char c;
375     int i,j;
376     char Prior[7][7] =
377     {
378        {'>','>','<','<','<','>','>'},
379        {'>','>','<','<','<','>','>'},
380        {'>','>','>','>','<','>','>'},
381        {'>','>','>','>','<','>','>'},
382        {'<','<','<','<','<','=',' '},
383        {'>','>','>','>',' ','>','>'},
384        {'<','<','<','<','<',' ','='}
385     };//  算符间的优先关系
386     char Opt[7]={'+','-','*','/','(',')','#'};
387     for(i=0;i<7;i++)
388     {
389         if(Popc.ch == Opt[i])
390             break;
391     }
392     for(j=0;j<7;j++)
393     {
394         if(Cr.ch == Opt[j])
395             break;
396     }
397     c=Prior[i][j];
398     return c;
399 }
400 
401 char *killzero(char *Str, double Result)//消除末尾的0
402 {
403     int i;
404     sprintf(Str,"%lf",Result);
405     i=strlen(Str)-1;
406     while(i && (Str[i] == '0'))
407     {
408         Str[i]='\0';
409         i--;
410     }
411     if(Str[i] == '.')
412         Str[i]='\0';
413     return Str;
414 }
415 
416 double Cal(char *pFormula)//计算表达式
417 {
418     struct Stack optr,opnd,*Poptr,*Popnd;
419     Poptr = &optr;
420     Popnd = &opnd;
421 
422     int i=0,j=0;
423     struct SNode Numa,Numb,Opr,Outopr,tem,result;
424     struct SNode *pNuma=&Numa;
425     struct SNode *pNumb=&Numb;
426     struct SNode *pOpr=&Opr;
427 
428     struct SNode *pOutopr=&Outopr;
429     struct SNode *presult=&result;
430     struct SNode *ptem=&tem;
431     result.data=0;
432 
433     struct SNode xTem,TemResult,Data,Crtem;
434 
435     char Temp[20]={'\0'},Cntem[2];
436     char CpFormula[102];
437     xTem.ch='#';
438 
439     InitStack(Poptr); //运算符栈
440     Push(Poptr, xTem);
441     InitStack(Popnd); //数字栈
442     Check(pFormula);
443 
444     while(*(pFormula+j) != '\0')
445     {
446         CpFormula[j]=*(pFormula+j);
447         j++;
448     }
449     CpFormula[j]='\0';
450     strcat(CpFormula, "#");
451     printf("\n%s\n", CpFormula);
452 
453 
454     while(CpFormula[i] != '\0')
455     {
456         if(((CpFormula[i] >= '0') && (CpFormula[i] <= '9'))||(CpFormula[i] == '.'))//当前为数字,或者.
457         {
458             Cntem[0]=CpFormula[i];
459             Cntem[1]='\0';
460             strcat(Temp, Cntem);
461             if((CpFormula[i+1] == '+') || (CpFormula[i+1] == '-')|| (CpFormula[i+1] == '*')|| (CpFormula[i+1] == '/')
462                     || (CpFormula[i+1] == '(')|| (CpFormula[i+1] == ')') || (CpFormula[i+1] == '#'))
463             {
464                 Data.data=(double)atof(Temp);
465                 Push(Popnd, Data);
466                 //printf("\nPush opnd\n");
467                 strcpy(Temp, "\0");
468             }
469             i++;
470         }
471         else //当前为操作符
472         {
473             Crtem.ch=CpFormula[i];
474             GetTop(optr, ptem);
475             switch (Judge(tem, Crtem))
476             {
477                case '<':   // 栈顶元素优先权低
478                 {
479                     Push(Poptr, Crtem);
480                     //printf("\nPush optr\n");
481                     i++;
482                     break;
483                 }
484                case '=':   // 脱括号并接收下一字符
485                 {
486                     Pop(Poptr, pOutopr);
487                     //printf("\nPop optr\n");
488                     i++;
489                     break;
490                 }
491                case '>':   // 退栈并将运算结果入栈
492                 {
493                     Pop(Poptr, pOpr);
494                     Pop(Popnd, pNumb);
495                     Pop(Popnd, pNuma);
496                     TemResult.data=Operate(Numa.data, Opr.ch, Numb.data);
497                     //printf("\n>  %.4f\n",y.data);
498 
499                     Push(Popnd, TemResult);
500                     break;
501                 }
502                default:
503                 {
504                     printf("\nError !\n");
505                     break;
506                 }
507             }
508         }
509     }
510 
511     Pop(Popnd, presult);
512     DestroyStack(Poptr);
513     DestroyStack(Popnd);
514     //printf("\n%.4f\n",result.data);*/
515     return result.data;
516 }
原文地址:https://www.cnblogs.com/tyche116/p/8508210.html