📄 calc.c
字号:
if(Debug) printf( "...Scaning:%c,Find:%f%c%f\n...Calculate to a New String:%s\n\n",
sOps[nOp][nPosInOpstr], nLeftnr,sOps[nOp][nPosInOpstr], nRightnr,chpString );
}
}
if(Debug) printf( "...Finish Calculate, The Result is: %s\n\n", chpString);
return chpString;
}
/* 主操作过程,输入式子串,返回 double 型结果,起着移除括号的重任 */
double Operation(char *chpString)
{
char szStrn[Max],szBuf1[Max],szBuf2[Max],szBuf3[Max],szBuf4[Max];
int nCount, nLastOpen;
strcpy(szStrn,chpString);
if(Debug) printf( "\n...Starting Bracket Removal Loop...\n");
while(FindChar(&szStrn[0],'('))
{
for (nCount=0; nCount<=Len_f(&szStrn[0]); nCount++) /* 不断地查找配对的括号... */
{
if (szStrn[nCount]=='(') /* 起始括号 */
{
nLastOpen=nCount; /* 最近一个'(' ,是指最接近 ')' 的那个,使之配对*/
}
if (szStrn[nCount]==')') /* 如果最近有一个配对的括号,就进入计算 */
{ /* 将括号内的字符串打印出来 */
if(Debug) printf("...In %s Find %s, Calling Calculate Unit...\n",szStrn,Midstr_f(&szStrn[0],&szBuf1[0],nLastOpen+2,nCount-nLastOpen-1));
/* 将括号中的结果计算出来,连同括号左边的字符串形成新的字符串放入缓冲区,再与括号右边的字符串形成新的字符串 */
/* 复合形式...有点难看懂.. 和 Calculate_f 中的基本一样 */
AddStrings_f(&szStrn[0],AddStrings_f(&szBuf1[0],Left_f(&szStrn[0],&szBuf3[0],nLastOpen),
Calculate_f(Midstr_f(&szStrn[0],&szBuf4[0],nLastOpen+2,nCount-nLastOpen-1))),
Right_f(&szStrn[0],&szBuf2[0],Len_f(&szStrn[0])-nCount-1));
if(Debug) printf("...New String: %s\n", szStrn);
nCount=Len_f(&szStrn[0])+1; /* 移动当前指向... */
}
}
}
if(Debug) printf("...Brackets Removed, Final String is:%s, Calculating...\n", szStrn);
/* 计算剩余的式子 */
Calculate_f(&szStrn[0]);
if (szStrn[0] == 0)
{
szStrn[0]='0';
szStrn[1]=0;
}
if(Debug) printf("...Finish Expression Calculate.\n");
return Val_f(szStrn); /* 返回计算结果 */
}
/* 式子的合法性检查 0 含有非法字符,1 正常 2 关系运算 */
int StrChk(char *chpSource)
{
char strIn[Max]; /* 源 */
char strTmp; /* 单个字符 */
int nCount=0;
int LB=0,RB=0; /* 括号计数变量 */
int nNexus=0;
int iLen;
strcpy(strIn,chpSource);
iLen=strlen(strIn);
/* 开头符号合法性检查 */
strTmp=strIn[0];
if(strTmp=='+') /* 移除多余的 '+' */
{
DelChar(strIn,0);
iLen--;
}
if(strTmp=='*'||strTmp=='/'||strTmp=='e'||strTmp=='E'||strTmp=='^'||strTmp==')'||strTmp=='='||strTmp=='>'||strTmp=='<')
{
printf("In %s Head Find Illegal Char:%c,",strIn,strTmp); /* 其实可以去掉非法字符在判断的... */
return 0;
} /* 返回错误信息 */
/* 结尾符号合法性检查 */
strTmp=strIn[strlen(strIn)-1];
if((strTmp>='0'&&strTmp<='9')||strTmp==')'); /* 注意,有个分号的 */
else
{
printf("In %s End Find Illegal Char:%c,",strIn,strTmp); /* 其实可以去掉非法字符在判断的... */
return 0;
}
for(nCount=0;strIn[nCount];nCount++) /* 检查是否有非法字符 */
{
strTmp=strIn[nCount];
if((strTmp>='0'&&strTmp<='9'||strTmp=='+'||strTmp=='-'||strTmp=='*'||strTmp=='/'||strTmp=='.'||strTmp=='e'||strTmp=='E'||
strTmp=='^'||strTmp=='('||strTmp==')'||strTmp=='='||strTmp=='>'||strTmp=='<'||strTmp=='#'||strTmp=='!'))
{ /* 展示可能出现的字符 */
if(strTmp=='='||strTmp=='>'||strTmp=='<'||strTmp=='!')
{ /* 检查关系操作符 */
if(strTmp!='!') /* != 检查,这样不利于以后的拓展 */
{
nNexus=1; /* Pass */
}
else
{
if (strIn[nCount+1]!='=')
{
printf("In %s Find \'!\',But The Next Char NOT \'=\',",strIn);
return 0;
}
else if (strIn[nCount-1]=='='||strIn[nCount-1]=='>'||strIn[nCount-1]=='<')
{
printf("In %s Find \'!\',But The Previous Char IS \'%c\',",strIn,strIn[nCount-1]);
return 0;
}
}
}
continue;
}
printf("In %s Find Illegal Char:%c,",strIn,strTmp); /* 其实可以去掉非法字符在判断的... */
return 0; /* 返回错误信息 */
}
/* 表达式的修复处理 */
for(nCount=0;strIn[nCount];nCount++)
{
strTmp=strIn[nCount]; /* 括号修复 */
if(strTmp=='('||strTmp==')')
{
if (strTmp=='(') LB++;
else RB++;
if(LB<RB)
{
InsChar(strIn,0,'(');
LB++;
nCount++;
iLen++;
if(Debug) printf("...Add a Left Bracket.\n");
}
}
}
LB=0; RB=0; /* 复位很重要,或者重新定义 */
for(nCount=0;strIn[nCount];nCount++)
{
strTmp=strIn[nCount]; /* 括号计数 */
if(strTmp=='(') LB++;
if(strTmp==')') RB++;
}
if (LB!=RB) /* 判断括号的对称性 */
{
if(abs(LB-RB)<Max-iLen) /* 添加括号前,判断是否会越界 */
{
if(LB>RB) /* 右括号配对 */
{
for(nCount=0;nCount<LB-RB;nCount++)
{
InsChar(strIn,iLen,')'); /* 在最右边插入 ')' */
iLen++;
}
if(Debug) printf("...The Result of Right Bracket Partnership:%s\n",strIn);
}
else if(LB<RB) /* 左括号配对 */
{
for(nCount=0;nCount<RB-LB;nCount++)
{
InsChar(strIn,0,'('); /* 在最左边插入 '(' */
}
if(Debug) printf("...The Result of Left Bracket Partnership:%s\n",strIn);
}
}
else
{
printf("Bracket NOT Partnership:%s\n",strIn);
return 0;
}
}
/* 补上 '(' 前的 '*' 以及处理后一个非法字符*/
for(nCount=1;strIn[nCount];nCount++)
{
if (strIn[nCount]=='(')
{
strTmp=strIn[nCount+1]; /* 取后一个字符 */
if(strTmp=='*'||strTmp=='/'||strTmp=='e'||strTmp=='E'||strTmp=='^'||strTmp=='<'||strTmp=='>'||strTmp=='='||strTmp==')')
{
printf("Find Err Operator In:%s,",strIn);
return 0;
}
strTmp=strIn[nCount-1]; /* 取前一个字符 */
if(strTmp>='0'&&strTmp<='9'||strTmp==')')
{
InsChar(strIn,nCount,'*');
nCount++;
if(Debug) printf("...The Result of Plus Operator \'*\':%s\n",strIn);
}
}
}
/* 补上 ')' 后的 '*' */
for(nCount=1;strIn[nCount];nCount++)
{
if (strIn[nCount]==')')
{
strTmp=strIn[nCount-1]; /* 取前一个字符 */
if(strTmp=='*'||strTmp=='/'||strTmp=='e'||strTmp=='E'||strTmp=='^'||strTmp=='<'||strTmp=='>'||strTmp=='='||strTmp=='(')
{
printf("Find Err Operator In:%s,",strIn);
return 0;
}
strTmp=strIn[nCount+1]; /* 取后一个字符 */
if(strTmp>='0'&&strTmp<='9'||strTmp=='(')
{
InsChar(strIn,nCount,'*');
nCount++;
if(Debug) printf("...The Result of Add Operator \'*\':%s\n",strIn);
}
}
}
/* 移除多余的 '+' */
for(nCount=1;strIn[nCount];nCount++)
{
if (strIn[nCount]=='+')
{
strTmp=strIn[nCount-1]; /* 取前一个字符,如果是下列字符,这判正号 */
if(strTmp=='+'||strTmp=='-'||strTmp=='*'||strTmp=='/'||strTmp=='e'||strTmp=='E'||strTmp=='^'||strTmp=='('||strTmp=='<'||strTmp=='>'||strTmp=='=')
{
DelChar(strIn,nCount);
iLen--;
if(Debug) printf("...The Result of Conversion Add \'+\' to \'0\':%s\n",strIn);
strTmp=strIn[nCount+1]; /* 取后一个字符,过滤三重字符 -Plus*/
if(strTmp=='+'||strTmp=='-'||strTmp=='*'||strTmp=='/'||strTmp=='e'||strTmp=='E'||strTmp=='^'||strTmp=='('||strTmp=='<'||strTmp=='>'||strTmp=='=')
{
printf("Have Overmany Operator In:%s,",strIn);
return 0;
}
}
}
}
/* 将 '-' 负号替换为 '#' */
if(strIn[0]=='-') strIn[0]='#';
for(nCount=1;strIn[nCount];nCount++)
{
if (strIn[nCount]=='-')
{
strTmp=strIn[nCount-1]; /* 取前一个字符,如果是下列字符,这判负号 */
if(strTmp=='+'||strTmp=='-'||strTmp=='*'||strTmp=='/'||strTmp=='e'||strTmp=='E'||strTmp=='^'||strTmp=='('||strTmp=='<'||strTmp=='>'||strTmp=='=')
{
strIn[nCount]='#';
if(Debug) printf("...The Result of Conversion Minus \'-\' to \'#\':%s\n",strIn);
strTmp=strIn[nCount+1]; /* 取后一个字符,过滤三重字符 -Plus*/
if(strTmp=='+'||strTmp=='-'||strTmp=='*'||strTmp=='/'||strTmp=='e'||strTmp=='E'||strTmp=='^'||strTmp=='('||strTmp=='<'||strTmp=='>'||strTmp=='=')
{
printf("Have Overmany Operator In:%s,",strIn);
return 0;
}
}
}
}
/* 重叠符号检查 */
for(nCount=1;strIn[nCount];nCount++)
{
strTmp=strIn[nCount];
if (strTmp=='+'||strTmp=='-'||strTmp=='*'||strTmp=='/'||strTmp=='^')
{
strTmp=strIn[nCount+1]; /* 取前一个字符,如果是下列字符,这判负号 */
if(strTmp=='+'||strTmp=='-'||strTmp=='*'||strTmp=='/'||strTmp=='^')
{
printf("Find Double Operator %c and %c,",strIn[nCount],strTmp);
return 0;
}
}
}
strcpy(chpSource,strIn);
return 1+nNexus; /* 通过合法检查 */
}
/* 传说中的主函数 */
int main(int argc, char *argv[])
{
Debug=0; /* Debug 调试开关 */
if (argc>1) /* 调试信息显示开关 */
{
Debug=!strcmp("/debug",argv[1]); /* 设置调试开关参数为 /debug */
if(Debug)
{
system("cls");
printf("\n\t\t\t\t == NOTE ==\n");
printf("\t\t * Debugging Information Has Opened *\n");
printf("\t * These Messages Primarily to the Process of Debugging Phase *\n");
printf("\t* This Information Reflects the Detailed Process of Calculating *\n");
printf("\t\t\t\t * NULL *\n");
printf("\n");
}
}
for(;;)
{
switch (Menu_Sel()) /* 返回选择的项目序号 */
{
case 0: case -21:case 'E'-'0': case 'e'-'0':
case 'X'-'0': case 'x'-'0': /* 退出 */
printf("\n\n\t\t Thank You Use ^_^ ...\n");
getch();
return 0;
case 1: case 'P'-'0': case 'p'-'0': /* 手工输入 */
Do_Press();
break;
case 2: case 'L'-'0': case 'l'-'0': /* 导入文件 */
Do_File();
break;
case 3: case 'C'-'0': case 'c'-'0': /* 清屏 */
system("cls");
break;
case 4: case 'A'-'0': case 'a'-'0': /* 显示关于 */
Show_About();
break;
case 20: /* 调试信息显示控制开关,隐藏的 */
if(Debug) /* 由大写的字母 'D' */
{
printf("\n\n\t************ Debugging Information Are Closed ************\n\n");
Debug=0;
}
else
{
printf("\n\n\t************ Debugging Information Has Opened ************\n\n");
Debug=1;
}
}
}
}
/* 显示关于 */
void Show_About()
{
system("cls");
printf("\n\t\t\t Expression Calculator V0.2\n");
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -