简单的四则运算计算器

#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方法调用有误!任意键退出...");
getchar();
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");
}
}
int 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;
}
}
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值