C语言计算器

 
 
/*******************

Powered By CCBUPT

Builder:NI3

2018-4-9

功能:使用C语言写的科学计算器,可以实现四则运算、三角函数运算、指对数运算;优先级正确;

能智能屏蔽空格,能识别输入错误和运算错误,

能实现继续运算、清空运算结果和有效退出的功能

********************/




#include <stdio.h>

#include <math.h>

#include <stdlib.h>

#include <corecrt_math_defines.h>

#define INPUT_MAX 1000

#define NODE_MAX 500

#define NUM_OPT 20

#define LEN_OPT 6

#define NUM_OPS 200




typedef enum {

Opd = 0,

Opt = 1

}Type;

typedef struct {

int opt;

double opd;

Type tp;

}Node;




//括号栈,检测括号是否匹配

char brackets[NUM_OPS];

int bb = 0;




int input(Node *in);

int translate(char *p, Node *re, int *len);

double translateopd(char *p, int *len);

int translateopt(char *p, int *len);

int cmp(const char *s, const char *d);

int calculate(Node *n, double *r);

int sclt(int opr, double *opd);

int dclt(int opr, double *opd1, double opd2);

int prid(int c);




/*功能:表达式输入和转换

*      接收输入并翻译为操作符和操作数存入表达式链

*输入:表达式链的地址

*输出:执行状态,正确返回1,错误返回0

*/

int input(Node *in)

{

//input->string

char ins[INPUT_MAX] = { 0 };

int insi = 0;

char temp_in = 0;

int len = 0;

//检测开头的空格

while (' ' == (ins[0] = getchar()));

//检测是不是直接输入了一个回车

if (ins[0] != '\n')

{

do {

temp_in = getchar();

//只能忽略多余空格

if (ins[insi] == ' '&&temp_in == ' ')

continue;

ins[++insi] = temp_in;

} while (temp_in != '\n');

ins[insi] = 0;

}




insi = 0;

//输入回车直接输出0

if (ins[0] == '\n')

in->tp = Opd, in->opd = 0.0, in++;

else

//压入表达式链

while (ins[insi])

{

if (translate(ins + insi, in++, &len))

insi += len;

else

return 0;

}

//自动添加等号

if ((in - 1)->opt != '=')

in->opt = '=', in->tp = Opt, in++;

in->opt = -1, in->tp = Opt;

return 1;

}

/*功能:翻译字符串为操作数或操作符

*输入:字符串地址,翻译返回节点,操作数和操作符长度返回地址

*输出:翻译结果状态

*/

int translate(char *p, Node *re, int *len)

{

if (*p >= '0'&&*p <= '9')

{

re->tp = Opd;

re->opd = translateopd(p, len);

return 1;

}

else if (*p == 'e' || *p == 'p')

{

if (*p == 'e')

{

re->tp = Opd;

re->opd = M_E;

*len = 1;

if (p[1] == ' ')

(*len)++;//十分重要,此处必须加括号

return 1;

}

else

{

if (p[1] == 'i')

{

re->tp = Opd;

re->opd = M_PI;

*len = 2;

if (p[2] == ' ')

(*len)++;

return 1;

}

else

return 0;

}

}

else

{

re->tp = Opt;

re->opt = translateopt(p, len);

if (re->opt)

return 1;

else

return 0;

}

}

/*功能:翻译操作数

*/

double translateopd(char *p, int *len)

{

int flag = 0;

int pointnum = 1;

double temp = 0;

int i = 0;

do {

if (!flag&&p[i] != '.')

temp = temp * 10 + p[i++] - '0';

else if (!flag&&p[i] == '.')

flag = 1, i++;

else

temp += (p[i++] - '0')*pow(0.1, pointnum), pointnum++;

} while ((p[i] >= '0'&&p[i] <= '9') || p[i] == '.');

if (p[i] == ' ')

i++;

*len = i;

return temp;

}

/*功能:翻译操作数

*      如果运算符非法,则返回0,合法则返回非零标志

*/

int translateopt(char *p, int *len)

{

char fu[NUM_OPT][LEN_OPT] = { "+","-","*","/","^","(",")","sin","cos","tan","asin","acos","atan","ln","lg","=" };

int fu_int[NUM_OPT] = { '+','-','*','/','^','(',')','s','c','t','s' + 'a','c' + 'a','t' + 'a','n','g','=' };

int i = 0;

for (i = 0; i<NUM_OPT; i++)

{

if (*len = cmp(p, fu[i]))

break;

}

if (i == NUM_OPT)

return 0;

if (p[*len] == ' ')

(*len)++;

return fu_int[i];

}

/*功能:字符串比较,返回字符长度

*      不匹配返回0

*/

int cmp(const char *s, const char *d)

{

char *dd = (char*)d;

while (*d)

if (*(d++) != *(s++))

return 0;

return d - dd;

}

/*功能:计算函数

*输入:表达式链地址,计算结果返回地址

*输出:成功与否

*/

int calculate(Node *n, double *r)

{

//双链栈

double OPRD[NUM_OPS] = { 0 };

int OPRT[NUM_OPS] = { 0 };

int db = 0;

int tb = 0;




int top = 0;

double a = 0.0, b = 0.0;

int o = 0;

int len = 0;

Node *nb = n;




if (n->tp == Opt && n->opt == '-')

OPRD[db] = 0.0, db++;//Push(&OPRD,0.0); 

while (1)

{

//判断前面有没有负号

if (n->tp == Opd)

{

OPRD[db] = n->opd, db++, n++;//Push(&OPRD,n->opd),n++;

}

else

{

//双目运算符

if (prid(n->opt))

{

//if(!GetTop(OPRT,&top))

if (tb)

top = OPRT[tb - 1];

if (!tb)

{

if (n->opt == '=' || n->opt == ')')

{

if (n->opt == ')')

{

bb--;//if(!Pop(&brackets,&temp))

if (bb<0)

{

printf("Bracket does not match!");

return 0;

}

}

break;

}

else

OPRT[tb] = n->opt, tb++, n++;//Push(&OPRT,n->opt),n++;

continue;

}

if (prid(top) == 0)

{

//Pop(&OPRD,&a);

//Pop(&OPRT,&o);

db--;

a = OPRD[db];

tb--;

o = OPRT[tb];

if (sclt(o, &a))

{

OPRD[db] = a, db++;//Push(&OPRD,a);

continue;

}

else

return 0;

}

if (prid(top) >= prid(n->opt))

{

//Pop(&OPRD,&b);

//Pop(&OPRD,&a);

//Pop(&OPRT,&o);

db--;

b = OPRD[db];

db--;

a = OPRD[db];

tb--;

o = OPRT[tb];

if (dclt(o, &a, b))

{

OPRD[db] = a, db++;//Push(&OPRD,a);

}

else

return 0;

}

else

{

OPRT[tb] = n->opt, tb++, n++;//Push(&OPRT,n->opt),n++;

}

}

else

{

//单目运算符和括号

double x = 0.0;

if (n->opt == '(')

{

brackets[bb] = '(', bb++;//Push(&brackets,'(');

if (len = calculate(n + 1, &x))

{

OPRD[db] = x, db++;//Push(&OPRD,x);

n += len, n++;

if (n->tp == Opt && n->opt == -1)

{

printf("Bracket does not match!");

return 0;

}

}

else

return 0;

}

else

{

OPRT[tb] = n->opt, tb++;//Push(&OPRT,n->opt);

n++;

}

}

}

}

*r = OPRD[db - 1];

return n - nb + 1;

}

/*功能:单目运算

*/

int sclt(int opr, double *opd)

{

switch (opr)

{

case 's':

*opd = sin(*opd);

break;

case 'c':

*opd = cos(*opd);

break;

case 't':

*opd = tan(*opd);

break;

case 'a' + 's':

if (*opd<-1 || *opd>1)

{

printf("Beyond asin()!");

return 0;

}

else

*opd = asin(*opd);

break;

case 'a' + 'c':

if (*opd<-1 || *opd>1)

{

printf("Beyond acos()!");

return 0;

}

else

*opd = acos(*opd);

break;

case 'a' + 't':

if (*opd>-3.141592654 / 2 && *opd<3.141592654 / 2)

*opd = atan(*opd);

else

{

printf("Beyond atan()!");

return 0;

}

break;

case 'n':

if (*opd>0)

*opd = log(*opd);

else

{

printf("Beyond ln()!");

return 0;

}

break;

case 'g':

if (*opd>0)

*opd = log10(*opd);

else

{

printf("Beyond lg()!");

return 0;

}

break;

}

return 1;

}

/*功能:双目运算

*/

int dclt(int opr, double *opd1, double opd2)

{

switch (opr)

{

case '+':

*opd1 = *opd1 + opd2; break;

case '-':

*opd1 = *opd1 - opd2; break;

case '*':

*opd1 = (*opd1)*opd2; break;

case '/':

if (opd2>pow(0.1, 8) || opd2<0 - pow(0.1, 8))

*opd1 = (*opd1) / opd2;

else

{

printf("Error 1/0 !");

return 0;

}

break;

case '^':

*opd1 = pow(*opd1, opd2); break;

}

return 1;

}

/*功能:判断优先级

*/

int prid(int c)

{

switch (c)

{

case '+':

case '-':

case '=':

case ')':

return 1; break;

case '*':

case '/':

return 2; break;

case '^':

return 3; break;

default:return 0; break;

}

}

int main()

{

int c = 0;

while (1)

{

Node nodes[NODE_MAX] = { 0 };

double r = 0.0;

//清空括号栈

bb = 0;//InitStack(&brackets);

printf("Enter: ");

//输入

if (!input(nodes))

{

printf("Input Error!");

continue;

}

//计算

if (calculate(nodes, &r))

{

if (bb)

{

printf("Bracket does not match!");

continue;

}

if (floor(r) == r)

printf("%d", (int)r);

else

printf("%.4f", r);

}

c = getchar();

if (c == 'q')//退出

break;

else if (c == 'c')//清屏

system("clear");

if (c != '\n')

getchar();

}

printf("Quit...\n");

return 0;

}

猜你喜欢

转载自blog.csdn.net/qq_38364138/article/details/80680877