注册 登录  
 加关注
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

耳朵的博客

做自己想做的人

 
 
 

日志

 
 

自己用C写的一个计算器  

2009-03-07 05:19:12|  分类: C |  标签: |举报 |字号 订阅

  下载LOFTER 我的照片书  |

/*****************************************************/
/*                    计算器                         */
/*                   By  耳朵                        */
/*                   2009.3.7                        */
/*****************************************************/
/*****************************************************/
/*                   功能描述:
  可计算任意长度带括号的四则算式表达式,精度为double 
                                                     */
/*****************************************************/
/*库文件包含*/
#include "stdio.h"
#include "stdlib.h"
#include "string.h"
/************/
#define STRING_LENGTH  1000
#define NUMBER_LENGTH  40
/*结构体定义*/
struct symbol
{
 char c;
 struct symbol *next;
}*symbol_head=NULL,*temp=NULL;

struct number
{
 double n;
 struct number *next;
}*number_head=NULL,*temp_2=NULL;

char result[NUMBER_LENGTH];

/**********/
/*函数声明*/
double ji_shuan(double a,char t,double b);/*两个double数据计算*/
void string_scan(char *str);/*字符串算式扫描*/
void operate(void);/*链表操作*/

void operate(void)/*链表操作*/
{
 temp=symbol_head->next;
 symbol_head->next=symbol_head->next->next;
 number_head->n=ji_shuan(number_head->next->n,temp->c,number_head->n);
 temp_2=number_head->next;
 number_head->next=number_head->next->next;
 free(temp);
 free(temp_2);
}

double ji_shuan(double a,char t,double b)/*两个double数据计算*/
{
    switch(t)
 {
  case '+':return a+b;break;
  case '-':return a-b;break;
  case '*':return a*b;break;
  case '/':return a/b;break;
  default :printf("ji_shuan方法调用有误!任意键退出...");getch();exit(0);//用于调试程序时出错指示
 }
}

void string_scan(char *str)/*字符串算式扫描*/
{
 int i=0;
 char temp_str[NUMBER_LENGTH];
 struct symbol *t;
 /*ecvt函数用到的变量*/
 char *string;        //存放字符串
 int ndig;            //字符串长度
 int dec;    //小数点位置
 int sign;       //正负标记
 /********************/
 t=(struct symbol *)malloc(sizeof(struct symbol));
 t->next=symbol_head;
 symbol_head=t;
 symbol_head->c='#';
 for(i=0;i<strlen(str);i++)
 {
  if((str[i]>='0'&&str[i]<='9')||(str[i]=='-'&&(str[i-1]<'0'||str[i-1]>'9')&&str[i-1]!=')'))//检测到数字,(出现"-"号,并且检测到前一个是除")"外的符号,则此为负号(不是减号),此数为负数)
  {
   struct number *t;
   int j=0;
   while((str[i]>='0'&&str[i]<='9')||str[i]=='.')
   {
    temp_str[j]=str[i];
    i++;
    j++;
   }
   temp_str[j]='\0';
   t=(struct number *)malloc(sizeof(struct number));
   t->next=number_head;
   number_head=t;
   number_head->n=atof(temp_str);//double atof(*char)为字符串转double函数
  }
  if(str[i]=='('||str[i]==')'||str[i]=='+'||str[i]=='-'||str[i]=='*'||str[i]=='/'||str[i]=='=')
  {
   struct symbol *t;
   t=(struct symbol *)malloc(sizeof(struct symbol));
   t->next=symbol_head;
   symbol_head=t;
   symbol_head->c=str[i];
   if((str[i]=='+'||str[i]=='-')&&symbol_head->next->c!='#'&&symbol_head->next->c!='(')
   {
    operate();
    if(symbol_head->next->c!='#'&&symbol_head->next->c!='(')
    {
     operate();
    }
   }
   else if((str[i]=='*'||str[i]=='/')&&(symbol_head->next->c=='*'||symbol_head->next->c=='/'))
   {
    operate();
   }
   else if(str[i]=='=')
   {
    while(symbol_head->next->c!='#')
    {
     operate();
    }
    temp=symbol_head;
    symbol_head=symbol_head->next->next;
    free(temp);
   }
   else if(str[i]==')')
   {
    while(symbol_head->next->c!='(')
    {
     operate();
    }
    temp=symbol_head;
    symbol_head=symbol_head->next->next;
    free(temp);
   }
  }
 }
 /*用于调试*/
 /*while(number_head!=NULL||symbol_head!=NULL)
 {
  if(number_head!=NULL)
  {
   printf("%f",number_head->n);
   number_head=number_head->next;
  }
  if(symbol_head!=NULL)
  {
   printf("%c",symbol_head->c);
   symbol_head=symbol_head->next;
  }
 }*/
 printf("以double型输出的结果:\n%f\n",number_head->n);
 gcvt(number_head->n,NUMBER_LENGTH,result);//调用double转字符串函数
 if(result[strlen(result)-1]=='.')//如果最后位是小数点,则去掉
 {
  result[strlen(result)-1]=result[strlen(result)];
 }
 printf("调用浮点型转字符串函数gctv的输出结果:\n%s\n",result);
 ndig=20;  //设置小数点后显示10位
 string = ecvt(number_head->n, ndig, &dec, &sign);
 printf("调用浮点型转字符串函数ectv的输出结果:\n字符串:%s   小数点在第%d位后   ",string,dec);
 if(sign==0)
 {
  printf("此数为正数\n");
 }
 else
 {
  printf("此数为负数\n");
 }
}

void main(void)/*入口函数*/
{
 char str[STRING_LENGTH];/*最大算式长*/
 int i=0,select=0;
 int bracket_flag=0;/*括号对称性标记*/
 while(1)
 {
root: bracket_flag=0;
  printf("请输入算式,允许带括号的加减乘除四则运算,以\"=\"号结束\n");
  scanf("%s",str);
  /*******算式查错*********/
  if((str[0]<'0'||str[0]>'9')&&str[0]!='-'&&str[0]!='(')
  {
   printf("算式错误!请重新输入...\n");
   goto root;
  }
  for(i=0;i<strlen(str)-1;i++)
  {
   if((str[i]<'0'||str[i]>'9')&&(str[i]!='+'&&str[i]!='-'&&str[i]!='*'&&str[i]!='/'&&str[i]!='('&&str[i]!=')'&&str[i]!='.'&&str[i]!='='))
   {
    printf("算式中含有非法字符!请重新输入...\n");
    goto root; 
   }
   
   else if(str[i]=='(') 
   {
    bracket_flag++;
   }
   else if(str[i]==')')
   {
    bracket_flag--;
    if(bracket_flag==-1)/*   出现先有")"的情况      */
    {
     printf("括号不匹配!请重新输入...\n");
     goto root;
    }
   }
   else if(str[i]=='=')
   {
    printf("算式中间不允许出现\"=\"号!请重新输入...\n");
    goto root; 
   }
   if((str[i]=='+'||str[i]=='-'||str[i]=='*'||str[i]=='/')&&(str[i+1]=='+'||str[i+1]=='-'||str[i+1]=='*'||str[i+1]=='/'||str[i+1]==')'))
   {
    printf("运算符输入有误!请重新输入...\n");
    goto root;
   }
   else if(str[i]=='('&&str[i+1]==')')
   {
    printf("括号内不可无数值!请重新输入...\n");
    goto root;
   }
   else if(str[i]==')'&&(str[i+1]!='+'&&str[i+1]!='-'&&str[i+1]!='*'&&str[i+1]!='/'))
   {
    printf("括号后不可无运算符!请重新输入...\n");
    goto root;
   }
  }
  if(bracket_flag!=0)
  {
   printf("括号不匹配!请重新输入...\n");
   goto root;
  }

  if(str[strlen(str)-1]!='=')//自动添加"="
  {
   printf("未输入\"=\"号,自动添加...\n");
   str[strlen(str)+1]=str[strlen(str)];
   str[strlen(str)]='=';
   puts(str);
  }
  string_scan(str);
  printf("\n计算完成!请选择:\n1.继续计算.\n2.退出.\n\n");
loop_2: scanf("%d",&select);
  switch(select)
  {
   case 1: break;
   case 2: exit(0);
   default :printf("选择错误!请重新选择...\n");goto loop_2;break;
  }
 }
}

  评论这张
 
阅读(947)| 评论(3)
推荐 转载

历史上的今天

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2017