C++编写简单计算器

来源:互联网 发布:通钢事件 知乎 编辑:程序博客网 时间:2024/05/16 09:01
#include<iostream.h>
#include<string.h>
#include<stdlib.h>
#include<fstream.h>
class  calculator
{
public:
calculator(char str1[100]);
~calculator();
 int check(char *c);//判断输入的表达式是否正确
 void  move(char *f, double *s,int p);//f存放字符,s存放数字 p:当前运算符数组的位置
 double convnum(char *c);//c 是由小数或正负数组成的表达式
 double good(char *c);  /*可递归函数*/
 int show();//输出函数
private:
 char str[100];
};
/*******************************************************/
calculator::calculator(char str1[100])
{
    strcpy(str,str1);
}
/*******************************************************/
calculator::~calculator()
{
}
/*******************************************************/
int calculator::check(char *c)//判断输入的表达式是否正确
{
 int k=0;
 int i=0;
 int len=strlen(c);
 while(*c!='\0')
 {
  if((*c>='0' && *c<='9') || *c=='+' ||
   *c=='-' || *c=='*' || *c=='/' ||
   *c=='.' || *c=='(' ||  *c==')' )
  {
  }
  else
  {
  cout<<"输入的表达式错误,请重新输入!"<<endl;
   return 0;
  }
       for(i=0;i<len;i++)
       {
         if(*c=='/'&&*(c+1)=='0')
         {
          cout<<"分母不能为零!"<<endl;
          return 0;
         }
        
      }
  if(*c=='(')
   k++;
  else if(*c==')')
   k--;
  
  c++;
 }
 if(k!=0)
 {
 cout<<"括号输入错误!"<<endl;
  return 0;
 }
 return 1;
}
/*************************************************************************/
void calculator::move(char *f, double *s,int p)//f存放字符,s存放数字 
{
 int i=0,len=strlen(f);
 for(i=p; i<len; i++)   /*将已经运算过的符号,空出来的位置用后面的符号来填充,*/     
 {                      /*即把乘和除号的位置用后面的加和减号填充*/
  f[i]=f[i+1];
  s[i]=s[i+1];
 }
 s[i]=s[i+1];
 f[len-1]='\0';
 
}
/***********************************************************************/
double calculator::convnum(char *c)//c 是由小数或正负数组成的表达式
{
 double num=0.0;//返回转换好的值。
 double a=1.0;
 int i=0,p=0,len=0;
 char temp[100];//存放小数点前的数据
 int tempi=0;
 int start=0;
 int f=1;   /*正负符号指示器,若为1则为正数,为-1,此数为负数*/
 
len=strlen(c);
 
 if(c[0]=='-')
 {
  start=1;
  f=-1;
 }
 for(i=start; i<len; i++)
 {
  if(c[i]=='.')
  {
   p=i;
   break;
  }
  temp[tempi++]=c[i];  /*将整数部分复制到temp[]中*/
 }
 temp[tempi]='\0';
 
 if(p!=0)
 {
  for(i=p+1;i<len;i++) /*将小数部分计算出来*/
 {
   if(c[i]=='.')  /*如果有多余的小数点,则表示输入错误*/
  {
   cout<<"小数点输入错误!"<<endl;
    exit(0);
   }
   a=a*0.1;
   num+=(a*(c[i]-48));/*数组temp每个存放了一位数字,并且是存放字符的(如果是数字,存放他的的ASCII码),其中0的ASCII码是48,1的ASCII码是49......为了把字符转回成数字,就要在它的ASCII码里减去48。*/
  }
 }
 a=1.0;
 len=strlen(temp);           /*计算整数部分*/
 for(i=len-1;i>=0; i--)
 {
  num=num+(a*(temp[i]-48));
  a*=10;
 }
 
 num=num*f;
 return num;
}
/***********************************************************************/
double calculator::good(char *c)  /*可递归函数*/ /*取得数值字符串,并调用convnum转换成double*/
{                   
 char g[100],number[30];  /*g,保存当前括号内的表达式串,number保存一个数的所有字符*/
 char f[80]; /*保存所有的符号的堆栈*/
 int fi=0; /*保存符号的位置指针*/
 double s[80]; /*保存当前所有的数的一个堆栈*/
 int si=0; /*保存数字位置指针*/
 int k=0; /* 若k=1则表示有两对括号*/
 int num=0,i=0; /*num保存新括号内的字符数,i 保存number里的字符位置*/
 int cc=0; /*乘除符号数量*/
 int jj=0; /*加减符号数量*/
 
    while(*c!='\0')
    {
       num=0;
    k=0;
     switch(*c)
     {
     case '*':
     case '/':
     case '+':
     case '-':
           f[fi++]=*c;
     if(*c=='*'||*c=='/')
                cc++;
     else
             jj++;
     if(*(c-1)!=')')
     {
         number[i]='\0';
      i=0;
      s[si++]=convnum(number);
     }
                 break;
     case '(':
      k++;
      while(k>0)
      {
         c++;
      g[num]=*c;
      num++;
      if(*c==')')
      {
       k--;
      }
                     else if(*c=='(')
      {
         k++;
      }
      }
        g[num-1]='\0';
     num=0;
     s[si++]=good(g);
     break;
     default:
      number[i++]=*c;
      if(*(c+1)=='\0')
      {
         number[i]='\0';
      s[si++]=convnum(number);
      }
       break;
     }
         c++;
    }
  
 
 f[fi]='\0';
 
 i=0;
 while(cc>0)
 {
  switch(f[i])
  {
  case '*': cc--;
   s[i+1]=s[i]*s[i+1];
   move(f,s,i);
   break;
  case '/': cc--;
   s[i+1]=s[i]/(float)s[i+1];
   move(f,s,i);
   break;
  default:
   i++;
   break;
  }
 }
 
 i=0;
 while(jj>0)
 {
  switch(f[i])
  {
  case '+': s[i+1]=s[i]+s[i+1];
   jj--;
   move(f,s,i);
   break;
  case '-': s[i+1]=s[i]-s[i+1];
   jj--;
   move(f,s,i);
   break;
  default:
  cout<<"操作错误!"<<endl;
   break;
  }
 }
 
 return s[0];
}
/***************************************************************/
int calculator::show()//输出函数
{
 double sum=0;
 sum=good(str);
 
ofstream fout("text");
 if(!fout)
 {
  cout<<"打不开该文件!"<<endl;
    return 1;
 }
 fout<<"输入的表达式:"<<str<<endl;
 fout<<"sum="<<sum<<endl;
 fout.close();
 cout<<sum;
 cout<<endl;
 return 0;
}
/*************************************************************/
void main()
{
 char str1[100];
 int p=1;
 while(1)
 {
 cout<<"请输入表达式,退出请输入exit!"<<endl;
 cin>>str1; 
        p=strcmp(str1,"exit");
  if(p==0)
   break;
  calculator A(str1);
  p=A.check(str1);
  
  if(p==0)
   continue;
  A.show();
 }
cout<<"再见!"<<endl;
}
阅读(522) | 评论(1) | 转发(0) |
0

上一篇:字符串String

下一篇:内存分配方式

相关热门文章
  • 学练太极拳十三要
  • Workqueue机制
  • 冷的好,冷的妙,冷到嘿嘿笑...
  • ASE中事物的隔离级别——基本...
  • NetBPM 安装
  • test123
  • 编写安全代码——小心有符号数...
  • 使用openssl api进行加密解密...
  • 一段自己打印自己的c程序...
  • sql relay的c++接口
  • 怎么样找出BIND中查询并发量多...
  • 可有人在实际的openstack生产...
  • 如下makefile如何编写
  • sqlldr 参数配置
  • 讨论一下各位所管理的mysql生...
给主人留下些什么吧!~~

何本俊夫2012-09-20 17:07:28

该程序在计算时分母为零的情况下不能做出判断

回复 | 举报
原创粉丝点击