zoukankan      html  css  js  c++  java
  • 基于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 }
  • 相关阅读:
    conda环境配置以及pyinstaller报错配置
    软件测试的艺术--读书笔记
    flex布局相关
    移动端特殊样式
    css3中的2D转换
    logo seo优化
    html5 简单的新特性
    css中溢出文字省略号方式
    css用户界面样式
    精灵图与字体图标相关
  • 原文地址:https://www.cnblogs.com/tyche116/p/8508210.html
Copyright © 2011-2022 走看看