1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
|
#include
#include
#include
int
main()
{
char
*s1;
int
i;
double
c;
double
calc(
char
*s);
int
brk(
char
*st);
while
(1)
{
s1=(
char
*)
malloc
(50);
//为s1分配地址和空间。
scanf
(
"%s"
,s1);
//输入并得到s1字符串。
i=brk(s1);
//执行所有"()"中的计算式。
c=calc(s1);
//计算最后的不带"()"的s1。
printf
(
"%g\n"
,c);
//输出最后结果。
printf
(
"--------Press Up/Down Arorw or Begain Next Input:\n"
);
//提示执行下一次运算。
free
(s1);
//释放s1内存空间。
}
}
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
|
#include
#include
#include
double
calc(
char
*s)
//把s拆解成double型数组和保存操作符的字符型数组,
{
//并利用两个数组计算结果。
int
i=0,j=0,k=0,num=1,end=0,sub=0;
//num、end、sub为开关标识。
double
*sn;
char
*sc,*sp;
void
mathc(
double
*a,
char
*s);
sn=(
double
*)
malloc
(51);
//用于存放s中所有的数字串。
sc=(
char
*)
malloc
(50);
//用于存放s中所有的操作符。
sp=(
char
*)
malloc
(10);
//遍历s中的各个数字串,并保存其中。
//while(!isdigit(*s))
// s++;
//c=*s;
//if(c=='-')
//{
// *sp=c;
// i=1;
// s++;
//}
for
(;*s!=
'\0'
;s++)
//遍历s所有字符。
{
if
(!
isdigit
(*s) && *s!=
'+'
&& *s!=
'-'
&& *s!=
'*'
&& *s!=
'/'
&&
(接上一行) *s!=
'.'
)
//如果字符不是数字且不是操作符及小数点则输出错误。
{
printf
(
"Error 6: illegal input!\n"
);
return
0;
}
if
(
isdigit
(*s)||*s==
'.'
)
//如果字符是个数字或者小数点。
{
//if(c=='-')
*(sp + i++)=*s;
//i++;
num=0;
//把这3个开关置为0。
end=0;
sub=0;
continue
;
}
if
(sub==1)
//sub用于标识s中负数,比如"-5",
//但是如果有两个"--"则是错误,
// 除了类似"4--5"【等价于4-(-5)】的情况。
{
//"--"前没有数字的情况是不允许的。
printf
(
"Error 7: too many operator!\n"
);
return
0;
}
if
(num==1)
//num==1说明是字符串刚开始(即第一个字符)
{
//或者上一次执行的是“+-*/”。
if
(*s!=
'-'
)
//开始不是"-"或"+*/"后面不是"-"。
{
//(注意在这个时候肯定也不是数字,
//因为数字已经被判断过了。)
printf
(
"Error 8: too many operator!\n"
);
return
0;
}
else
{
*(sp + i++)=*s;
//开始是个"-"或者前一个字符是"+*/"。
sub=1;
//把sub置为1,即下一个字符不能再是"-",
//注意这是在num==1的情况下。
end=0;
//执行的是数字字符部分,此程序把
//这种情况下的负号做为了数字的一部分。
continue
;
//执行下一次循环。
}
}
if
(*s==
'+'
||*s==
'-'
||*s==
'*'
||*s==
'/'
)
//如果执行的字符是操作符。
{
*(sp+i)=
'\0'
;
//是sp结束,即结束数字字符部分。
i=0;
//使下一次sp从0开始计数。
end=1;
//标识数字字符部分执行结束。
*(sn + j++)=
atof
(sp);
//把sp转换为double型数组。
if
(*(s+1)==
'\0'
)
//如果下一个元素为s的的结束,
//则不往下执行,即不保存这个操作符。
break
;
*(sc + k++)=*s;
//既然s的下一个元素不是结束,
//那么把这个字符串保存到sc中。
num=1;
//因为刚保存的是个操作符,
//下一个不能再是操作符,除了"-"。
continue
;
}
}
if
(*s==
'\0'
&&end==0)
//s的最后一个字符是数字字符,执行这一部分语句。
{
*(sp+i)=
'\0'
;
//使sp结束。
//i=0;
if
(*(sp+i-1)==
'-'
)
//如果上一个字符只是一个"-"号,则输出错误。
{
printf
(
"Error 9: illegal input!\n"
);
return
0;
}
*(sn + j++)=
atof
(sp);
//把sp转换成double数组保存到sn中。
}
*(sn+j)=
'\0'
;
//是sn和sc结束。
*(sc+k)=
'\0'
;
mathc(sn,sc);
//把sn和sc传给mathc函数计算s的结果。
return
*sn;
//mathc的计算结果是保存在sn中的,
}
//把sn返回即可。
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
|
#include
void
mathc(
double
*a,
char
*s)
//执行计算。
{
int
i;
double
sum;
void
offsetd(
double
*s,
int
n1,
int
n2);
void
offsetc(
char
*s,
int
n1,
int
n2);
for
(i=0;*(s+i)!=
'\0'
;i++)
//先计算“/”。
if
(*(s+i)==
'/'
)
{
if
(*(a+i+1)==0)
//不能除以0。
{
printf
(
"Error 5: illegal input 0!\n"
);
break
;
}
sum = *(a+i) / *(a+i+1);
*(a+i)=sum;
offsetd(a,i+1,1);
offsetc(s,i,1);
i=-1;
}
for
(i=0;*(s+i)!=
'\0'
;i++)
//计算"*"。
if
(*(s+i)==
'*'
)
{
sum = *(a+i) * *(a+i+1);
*(a+i)=sum;
offsetd(a,i+1,1);
offsetc(s,i,1);
i=-1;
}
for
(i=0;*(s+i)!=
'\0'
;i++)
//计算"-"。
if
(*(s+i)==
'-'
)
{
sum = *(a+i) - *(a+i+1);
*(a+i)=sum;
offsetd(a,i+1,1);
offsetc(s,i,1);
i=-1;
}
for
(i=0;*(s+i)!=
'\0'
;i++)
//计算"+"。
if
(*(s+i)==
'+'
)
{
sum = *(a+i) + *(a+i+1);
*(a+i)=sum;
offsetd(a,i+1,1);
offsetc(s,i,1);
i=-1;
}
}
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
|
#include
#include
void
offsetd(
double
*s,
int
n1,
int
n2)
//使double数组的n1+n2处的元素往前移动n2。
{
for
(;*(s+n1)!=
'\0'
;n1++)
*(s+n1) = *(s+n1+n2);
}
void
offsetc(
char
*s,
int
n1,
int
n2)
//与offsetd功能相同,只是s数组元素是字符型。
{
for
(;*(s+n1)!=
'\0'
;n1++)
*(s+n1) = *(s+n1+n2);
}
void
repl(
char
*c1,
char
*c2,
int
i,
int
j)
//使用c2替换c1中第i-j之间的元素。
{
unsigned
int
n=0;
int
a;
n=
strlen
(c2);
for
(a=n;*(c1+j)!=
'\0'
;)
//先把c1中第j元素以后的数字复制到c2后面。
*(c2 + a++) = *(c1 + j++);
*(c2+a)=
'\0'
;
for
(;*c2 !=
'\0'
;)
//用c2替换c1中第i元素往后的所有元素。
*(c1 + i++) = *(c2++);
*(c1+i)=
'\0'
;
}
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
|
#include
#include
#include
int
brk(
char
*st)
//计算括号内的算式的值。
{
int
m,n,d,b;
//m左括号位置,n遍历整个st数组,d右括号位置,b用于上s2数组。
char
*s2;
double
i;
void
repl(
char
*c1,
char
*c2,
int
i,
int
j);
//调用repl函数使用s2计算结果
//替换st中相应位置的字符。
//void mathc(double *a,char *s);
double
calc(
char
*s);
//计算字符串s的值。
s2=(
char
*)
malloc
(50);
//为s2分配内存空间,并返回空间地址。
for
(n=0;*(st+n)!=
'\0'
;n++)
//遍历st数组。
if
(*(st+n)==
')'
)
//首先查找")"。重要!在多重括号
//中查找")"才能有效的找到每组括号。
{ d=n;
//把"("的位置保存在d中。
if
(*(st+d+1)!=
'\0'
&&
isdigit
(*(st+d+1)))
//st的下一位是个数字则
//输出错误并返回。
{
printf
(
"Error 1: ();\n"
);
return
0;
}
while
(n>0&&*(st + --n)!=
'('
)
//从")"的位置n往回查找"("。
;
if
(*(st+n)!=
'('
)
//while语句执行完成,此时n==0;
//但是*(st+n)不是"(",则意味着没有匹配的
//"(",输出错误。
{
printf
(
"Error 2: ();\n"
);
return
0;
}
m=n;
//找到"("的话,把n的值保存到m中。
if
(m>0 &&
isdigit
(*(st+m-1)))
//m位置的上一位不能是数字。
{
printf
(
"Error 3: ();\n"
);
return
0;
}
if
((d-m)==1)
//如果"()"为空,输出错误。
{
printf
(
"Error 4: ();\n"
);
return
0;
}
for
(b=0;*(st + ++n)!=
')'
;b++)
//把括号中的内容复制到s2中。
*(s2+b) = *(st + n);
*(s2+b)=
'\0'
;
i=calc(s2);
//计算s2的值,并返回double i。
sprintf
(s2,
"%g"
,i);
//把i转换成字符串保存至s2中。
//printf("s2 %s\n",s2);
repl(st,s2,m,n+1);
//使用s2替换st中的括号。
printf
(
"step %s\n"
,st);
//输出替换后的st。
n=-1;
//执行下一次循环。
continue
;
}
}
|