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 }
  • 相关阅读:
    Linux文件属性
    [Oracle] Listener的动态注册
    jQuery easyUI Pagination控件自定义div分页(不用datagrid)
    桂林电子科技大学出校流量控制器Android版1.0.0
    php使用check box
    Python windows ping
    Python selenium chrome 环境配置
    Linux wget auto login and backup database
    PyQt4 ShowHMDB show sqlite3 with QTableWidget summary
    PyQt4 py2exe 打包 HardwareManager
  • 原文地址:https://www.cnblogs.com/tyche116/p/8508210.html
Copyright © 2011-2022 走看看