您的位置:首页 > 编程语言 > C语言/C++

简单计算器

2018-01-30 21:51 239 查看
 突然想到学了这么长时间C语言,除了写题,似乎没干过别的事了。。。


 闲着写了一个计算器,纯手工模拟,虽然只能实现简单的加减乘除和取余。。。。(弱鸡)

不过在输入合法性的判断上非常严格,
欢迎指正

/*****************************************************************************************
******作者:boy
******文件描述:实现简单功能的计算器 ,支持 + ,- ,* ,/ ,% ,( ),整数,浮点数的多实例运算
******编译环境:Dev-C++
******修改日期: 2018.1.2
******版本:1.0.20
*****************************************************************************************/
#include<stdio.h>
#include<math.h>
#include<ctype.h>
#include<string.h>
#include<stdlib.h>
#define id double
/*************************栈********************************/
char E[10010]; // 表达式
int F=0;
struct S
{
int a[1000];
int top;
}ww;
/***********************运算函数****************************/
id _add(id a,id b); // +
id _sub(id a,id b); // -
id _mul(id a,id b); // *
id _div(id a,id b); // /
id _fmod(id a,id b);// %
//int fact(int a); // x!
//double _sin(double a); // sinx
//double _cos(double a); // cosx
//double _tan(double a); // tanx
//double _log(double a); // lnx
//double _fabs(double a); // |x|
//double _pow(double a,double b); // pow(x,y);
/*************************主要函数*********************************/
void printf0(); //界面函数
void printf1(); //开始函数
void printf2(); //界面函数
void printf3(); //界面函数
int mistake_(char *Ee); //判断非法输入
void removes(char *Ee); //去括号
void operation(char *Ee); //计算表达式
/*******************************主函数****************************/
int main()
{
printf0();
return 0;
}
/****************************************************************************/
int mistake_(char *Ee)
{
int i;
{ //括号不匹配
int q;
int h,t;
q = 0;
h = t = 0;
ww.top = 0;
memset(ww.a , '\0' , sizeof(ww.a));
for(i = 0;i < strlen(Ee);i ++){
if(Ee[i] == '(')
ww.a[ww.top ++] = '(';
else if(Ee[i] == ')'){
if(ww.top != 0)
ww.top --;
else{
q = 1;
break;
}
}
}
if(ww.top != 0 || q){
printf("输入非法 ! 请重新输入!\n");
return 1;
}
}
{ //其他非法
int flag = 0;
for(i = 0 ;i < strlen(Ee);i ++) {
//左括号
if(Ee[i] == '('){
if(i){
if(Ee[i - 1] == '(' || Ee[i - 1] == '+' || Ee[i - 1] == '-' || Ee[i - 1] == '*' || Ee[i - 1] == '/' || Ee[i - 1] == '%');
else
flag = 1;
}
if(Ee[i + 1] != '(' && Ee[i + 1] != ')' && Ee[i + 1] != '-' && !isdigit(Ee[i + 1]))
flag = 1;
}
//右括号
if(Ee[i] == ')'){
if(Ee[i - 1] != '(' && Ee[i - 1] != ')' && !isdigit(Ee[i- 1]))
flag = 1;
if(Ee[i + 1] != '\0'){
if(Ee[i + 1] != ')' && Ee[i + 1] != '+' && Ee[i + 1] != '-' && Ee[i + 1] != '*' && Ee[i + 1] != '/' && Ee[i + 1] != '%')
flag = 1;
}
}
//数字
if(isdigit(Ee[i])){
if(i){
if(Ee[i - 1] != '.' && !isdigit(Ee[i - 1]) && Ee[i - 1] != '(' && Ee[i - 1] != '+' && Ee[i - 1] != '-' && Ee[i - 1] != '*' && Ee[i - 1] != '/' && Ee[i - 1] != '%')
flag = 1;
}
if(Ee[i + 1] != '\0'){
if(Ee[i + 1] != '.' && !isdigit(Ee[i + 1]) && Ee[i + 1] != ')' && Ee[i + 1] != '+' && Ee[i + 1] != '-' && Ee[i + 1] != '*' && Ee[i + 1] != '/' && Ee[i + 1] != '%')
flag = 1;
}
}
//运算符
if(Ee[i] == '+' || Ee[i] == '-' || Ee[i] == '*' || Ee[i] == '/' || Ee[i] == '%'){
if(Ee[i + 1] == '\0')
flag = 1;
if(!i && Ee[i] != '-')
flag = 1;
if(Ee[i + 1] != '-' && Ee[i + 1] != '(' && !isdigit(Ee[i + 1]))
flag = 1;
if(Ee[i] != '-'){
if(Ee[i - 1] != ')' && !isdigit(Ee[i - 1]))
flag = 1;
}
else{
if(i){
if(Ee[i - 1] != '(' && Ee[i - 1] != ')' && !isdigit(Ee[i - 1]) && Ee[i - 1] != '+' && Ee[i - 1] != '-' && Ee[i - 1] != '*' && Ee[i - 1] != '/' && Ee[i - 1] != '%')
flag = 1;
if(Ee[i - 1] == '+' || Ee[i - 1] == '-' || Ee[i - 1] == '*' || Ee[i - 1] == '/' || Ee[i - 1] == '%'){
if(!isdigit(Ee[i + 1]))
flag = 1;
}
}
}
}
//小数点
if(Ee[i] == '.'){
if(!isdigit(Ee[i - 1]) || !isdigit(Ee[i + 1]))
flag = 1;
}
//其他字符
if(Ee[i] != '(' && Ee[i] != ')' && Ee[i] != '.' && !isdigit(Ee[i]) && Ee[i] != '+' && Ee[i] != '-' && Ee[i] != '*' && Ee[i] != '/' && Ee[i] != '%')
flag = 1;
}
if(flag == 1){
printf("输入非法 ! 请重新输入!\n");
return 1;
}
}
return 0;
}
/****************************************************************************/
void removes(char *Ee)
{
char *h,*t;
char a[10000],b[10000],c[10000];//存储表达式的三个部分,括号前,括号内,括号后
// char *aa = a,*bb = b,*cc = c; //对应指针
int i,q = 0;
//记录需要去除的括号数
for(i = 0;i < strlen(Ee);i ++)
if(Ee[i] == '(')
q ++;
while(q --){
memset(a,'\0',sizeof(a));
memset(b,'\0',sizeof(b));
memset(c,'\0',sizeof(c));
strcpy(a,Ee);
h = strrchr(a,'('); //寻找最内层的左括号
t = strchr(a,')'); //寻找最内层的右括号
strcpy(c,t + 1); //保存最内层括号右边的部分
strcpy(t + 1,"\0"); //删除 最内层括号右边的部分
strcpy(b,h); //保存最内层括号部分
strcpy(h,"\0"); //删除最内层括号部分 ,这里通过删除括号和括号后面的部分得到括号左边的部分
if(strlen(b) == 2){ //若b为空 ,更新
strcat(a,c);
strcpy(Ee,a);
continue;
}
else{ //计算b的值,并更新
strcpy(b,b + 1); //删除括号
b[strlen(b) - 1] = '\0';
//计算
int flag = 0;
for(int i=0;i < strlen(b);i ++){
if(b[i] == '+' || b[i] == '-' || b[i] == '*' || b[i] == '/' || b[i] == '%')
flag ++;
}
if(flag > 1 || (flag == 1 && b[0] != '-')) //若多于一个运算符或少于一个运算符且不是负数则进入运算函数
operation(b);
//更新
if(strlen(a) != 0){ //若括号前部分不为空,连接括号前,括号内,括号后部分,并更新
strcat(a,b);
strcat(a,c);
strcpy(Ee,a);
}
else{ //反之,连接括号内,括号后部分,并更新
strcat(b,c);
strcpy(Ee,b);
}
}
}
}
/****************************************************************************/
void operation(char *Ee)
{
char E[10000];
char a[10000],b[10000],c[10000];
char *aa,*cc;
strcpy(E,Ee);
int flag = 0;
int i;
int h,t;
double x,y,sum; //存储运算数和结果
for(i = 0;i < strlen(E);i ++){
if(E[i] == '+' || E[i] == '-' || E[i] == '*' || E[i] == '/' || E[i] == '%')
flag ++;
}
if(flag == 1 && E[0] == '-')
return ;
//计算乘,除,取余
for(i = 0; i < strlen(E);i ++){
h = t = x = y = sum = 0;
memset(a,'\0',sizeof(a));
memset(b,'\0',sizeof(b));
memset(c,'\0',sizeof(c));
if(E[i] == '*' || E[i] == '/' || E[i] == '%'){
h = i - 1;
while(h >= 0 && h < strlen(E) && (isdigit(E[h]) || E[h] == '.')){
if(h == 0){
break;
}
h --;
}
t = i + 1;
if(E[t
4000
] == '-')
t ++;
while(t >= 0 && t < strlen(E) && (isdigit(E[t]) || E[t] == '.')){
t ++;
}
if(h != 0 && isdigit(E[h - 1]))
h ++;
sscanf(E + h,"%lf",&x);
sscanf(E + i + 1,"%lf",&y);
strcpy(a,E);
strcpy(c,E + t); //得到表达式后半部分
strcpy(a + h,"\0"); //得到表达式前半部分
//计算
switch (E[i])
{
case '*':{
sum = _mul(x,y);
break;
}
case '/':{
if(!y){
printf("输入非法 ! 请重新输入!\n");
F = 1;
break;
}
sum = _div(x,y);
break;
}
case '%':{
if(!y){
printf("输入非法 ! 请重新输入!\n");
F = 1;
break;
}
sum = _fmod(x,y);
break;
}
}
sprintf(b,"%lf",sum); //将结果写入字符串
//更新
if(strlen(a) != 0){
strcat(a,b);
strcat(a,c);
strcpy(E,a);
}
else{
strcat(b,c);
strcpy(E,b);
}
i = h; //更新i
// flag --; //更新flag
}
}
//计算加,减
for(i = 0; i < strlen(E);i ++){
h = t = x = y = sum = 0;
memset(a,'\0',sizeof(a));
memset(b,'\0',sizeof(b));
memset(c,'\0',sizeof(c));
if(E[i] == '+' || E[i] == '-'){
if(i)
h = i - 1;
else
h = i;
while(h >= 0 && h < strlen(E) && (isdigit(E[h]) || E[h] == '.')){
if(h == 0){
break;
}
h --;
}
t = i + 1;
if(E[t] == '-')
t ++;
while(t >= 0 && t < strlen(E) && (isdigit(E[t]) || E[t] == '.')){
t ++;
}
if(h != 0 && isdigit(E[h - 1]))
h ++;
sscanf(E + h,"%lf",&x);
if(h != i)
sscanf(E + i + 1,"%lf",&y);
// printf("!%d %d",x,y);
strcpy(a,E);
strcpy(c,E + t); //得到表达式后半部分
strcpy(a + h,"\0"); //得到表达式前半部分
//计算
switch (E[i])
{
case '+':{
sum = _add(x,y);
break;
}
case '-':{
sum = _sub(x,y);
break;
}
}
sprintf(b,"%lf",sum); //将结果写入字符串
//更新
if(strlen(a) != 0){
strcat(a,b);
strcat(a,c);
strcpy(E,a);
}
else{
strcat(b,c);
strcpy(E,b);
}
i = h; //更新i
}
}
strcpy(Ee,E); //更新表达式
}
/****************************************************************************/
void printf0()
{
char q[10000];
int choice;
system("cls");
printf("\n\n\t\t ___________________________________________________________ \n");
printf("\t\t| |\n");
printf("\t\t| |\n");
printf("\t\t| |\n");
printf("\t\t| 欢 迎 使 用 本 计 算 器 |\n");
printf("\t\t| |\n");
printf("\t\t| 1.进入计算 |\n");
printf("\t\t| |\n");
printf("\t\t| 2.使用帮助 |\n");
printf("\t\t| |\n");
printf("\t\t| 3.关于 |\n");
printf("\t\t| |\n");
printf("\t\t| 4.退出 |\n");
printf("\t\t| |\n");
printf("\t\t| |\n");
printf("\t\t| |\n");
printf("\t\t| |\n");
printf("\t\t|___________________________________________________________|\n");
printf("\n\n\t\t\t请输入相应序号:\t");
while(scanf("%s",q ) != EOF){
if(strlen(q) != 1)
{
printf( "输入错误,请重新输入:" );
continue;
}
sscanf(q,"%d",&choice);
if(choice != 1 && choice != 2 && choice != 3 && choice != 4)
printf( "输入错误,请重新输入:" );
else
break;
}
system("cls");
if(choice == 1)
{
printf1();
}
else if(choice == 2)
{
printf2();
}
else if(choice==3)
{
printf3();
}
else if(choice==4)
{
printf("谢谢使用!\n");
exit(0);
}
return ;
}
/*********************************************************************/
void printf3()
{
printf("\n\n\t\t ___________________________________________________________ \n");
printf("\t\t| |\n");
printf("\t\t| |\n");
printf("\t\t| |\n");
printf("\t\t| 开发人员: |\n");
printf("\t\t| |\n");
printf("\t\t| |\n");
printf("\t\t| |\n");
printf("\t\t| |\n");
printf("\t\t| |\n");
printf("\t\t| |\n");
printf("\t\t| |\n");
printf("\t\t| |\n");
printf("\t\t| |\n");
printf("\t\t| |\n");
printf("\t\t| |\n");
printf("\t\t|___________________________________________________________|\n");
system("pause");
printf0();
return ;
}
/*********************************************************************/
void printf2()
{
printf("\n\n\t\t ___________________________________________________________ \n");
printf("\t\t| |\n");
printf("\t\t| |\n");
printf("\t\t| |\n");
printf("\t\t| 本计算器支持整数、浮点数的四则运算和取余运算 |\n");
printf("\t\t| |\n");
printf("\t\t| 另支持包含小括号的多项表达式的求值 |\n");
printf("\t\t| |\n");
printf("\t\t| |\n");
printf("\t\t| |\n");
printf("\t\t| |\n");
printf("\t\t| |\n");
printf("\t\t| |\n");
printf("\t\t| |\n");
printf("\t\t| |\n");
printf("\t\t| |\n");
printf("\t\t| |\n");
printf("\t\t|___________________________________________________________|\n");
system("pause");
printf0();
return ;
}
/*********************************************************************/
void printf1()
{
while(1){
puts("\n\t\t输入:t,退出本系统,输入:h,返回主界面\n");
while(gets(E) != NULL){
if(strcmp("t",E) == 0){
system("cls");
printf("谢谢使用!\n");
exit(0);
}
if(strcmp("h",E) == 0){
printf0();
continue;
}
F = 0;
if(mistake_(E)) //判断是否非法输入
continue;
// puts("合法!");
removes(E); //去括号
// puts("去除括号!");
// puts(E) ;
operation(E); //计算表达式
if(F) //除数为0或者取余数为0时
continue;
if(strlen(E) == 0)
puts("请输入表达式!");
else
puts("计算完成!");
puts(E); //输出
}
}
return ;
}
/*********************************************************************/
id _add(id a,id b)
{
return a + b;
}
id _sub(id a,id b)
{
return a - b;
}
id _mul(id a,id b)
{
return a * b;
}
id _div(id a,id b)
{
return a / b;
}
id _fmod(id a,id b)
{
return (id)fmod(a,b);
}
//double _log(double a)
//{
// return log(a);
//}
//double _fabs(double a)
//{
// return fabs(a);
//}
//double _pow(double a,double b)
//{
// return pow(a,b);
//}

后续可能会补充更新。。。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息