📄 jisuanqinew.cpp
字号:
else nOp=0;
if(Debug) cout<<nOp<<endl;
for (nCount=nOppos-2; nCount>=0; nCount--) // 向左边查找操作符
{
if ((*(chpString+nCount)=='+')||(*(chpString+nCount)=='/')||(*(chpString+nCount)=='-')||(*(chpString+nCount)=='*')||(*(chpString+nCount)=='^'))
{
if ((nCount>1)&&((*(chpString+nCount-1)=='e')||(*(chpString+nCount-1)=='E')||(*(chpString+nCount-1)=='^'))) continue; // 注意 1e-1 等,'-' 并不是单独的操作符
nLeftnr=Val_f(Midstr_f(chpString,&szBuf1[0], nCount+2, nOppos-nCount-2)); // 符号左边的字符串变为数值
nCount=-1;
}
else if (nCount==0) // 如果从头开始复制...
{
nLeftnr=Val_f(Left_f(chpString,&szBuf1[0],nOppos-1));
}
}
if(Debug) cout<<"...Left Operand:"<<nLeftnr<<endl;
// 提取右边的操作数计算
for (nCount=nOppos;nCount<Len_f(chpString);nCount++)
{
if ((*(chpString+nCount)=='+')||(*(chpString+nCount)=='/')||(*(chpString+nCount)=='-')||(*(chpString+nCount)=='*')||(*(chpString+nCount)=='^'))
{
if ((*(chpString+nCount-1)=='e')||(*(chpString+nCount-1)=='E')||(*(chpString+nCount-1)=='^')) continue; //注意 1e-1 等,'-' 并不是单独的操作符
nRightnr=Val_f(Midstr_f(chpString,&szBuf2[0],nOppos+1,nCount-nOppos)); // 符号右边的字符串变为数值
nCount=Len_f(chpString);
}
else if (nCount==Len_f(chpString)-1)
{
nRightnr=Val_f(Right_f(chpString,&szBuf2[0],Len_f(chpString)-nOppos));
}
}
if(Debug) cout<<"...Right Operand:"<<nRightnr<<endl;
if (sOps[nOp][nPosInOpstr]=='+') // 加
{ nResult=nLeftnr+nRightnr; }
else if (sOps[nOp][nPosInOpstr]=='-') // 减
{ nResult=nLeftnr-nRightnr; }
else if (sOps[nOp][nPosInOpstr]=='/') // 除
{ nResult=nLeftnr/nRightnr; }
else if (sOps[nOp][nPosInOpstr]=='*') // 乘
{ nResult=nLeftnr*nRightnr; }
else if (sOps[nOp][nPosInOpstr]=='^') // 次方/开方
{ nResult=pow(nLeftnr,nRightnr);}
// 组建新的字符串
// 格式AddStrings_f(目标,源1,源2)
AddStrings_f(&szBuf3[0], Left_f(chpString,&szBuf4[0],nOppos-Len_f(&szBuf1[0])-1), Str_f(nResult,&szBuf5[0]));
AddStrings_f(chpString, &szBuf3[0],Right_f(chpString,&szBuf5[0],Len_f(chpString)-nOppos-Len_f(&szBuf2[0])));
if(Debug) cout<<"...Scaning:"<<sOps[nOp][nPosInOpstr]<<"Find:"<<nLeftnr<<sOps[nOp][nPosInOpstr]<<nRightnr<<endl<<"...Calculate to a New String:"<<chpString<<endl<<endl;
}
}
if(Debug) cout<<"...Finish Calculate, The Result is:"<< chpString<<endl<<endl;
return chpString;
}
double Operation(char *chpString) // 主操作过程,输入式子串,返回 double 型结果,起着移除括号的重任
{
char szStrn[Max],szBuf1[Max],szBuf2[Max],szBuf3[Max],szBuf4[Max];
int nCount, nLastOpen;
strcpy(szStrn,chpString);
if(Debug) cout<<endl<< "...Starting Bracket Removal Loop..."<<endl;
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; // 通过合法检查
}
void Expression(void) // 计算表达式函数
{
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();
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'
{
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -