?? strtooper.cpp
字號(hào):
//
// StrToOper.cpp: Change a CSting to operation and calculate it
//copyright @ luda lartely@163.com
//////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "StrToOper.h"
#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
void CStrToOper::Clear(void)
{
ErrId=0;
Expression="";
Result=0.0;
x=0.0;
}
void CStrToOper::Initial(CString operation,double input)
{ ErrId=0;
Result=0.0;
int i;
Expression=operation;
x=input;
CString unilligel=" _[]!@#$%&|\';:<>,?";
for (i=0;i<unilligel.GetLength();i++)
Expression.Remove(unilligel.GetAt(i));//去除非法的字符
CString strPI,strX;
strX.Format("%4.6f",x);
Expression.Replace("exp","EXP");
Expression.Replace("x",strX);
strPI.Format("%4.6f",3.1415926);
Expression.Replace("pi",strPI);
Expression.MakeLower();
ErrCheck();
}
void CStrToOper::ErrCheck(void)
{
int leftParenthese=0,rightParenthese=0;
int i;
for (i=0;i<Expression.GetLength();i++)
{
if (Expression.GetAt(i)=='(')
leftParenthese++;
if (Expression.GetAt(i)==')')
rightParenthese++;
}
if (leftParenthese<rightParenthese)
{
ErrId=ERR_MISSLEFTPARA;
return;
}
if (leftParenthese>rightParenthese)
{
ErrId=ERR_MISSRIGHTPARA;
return;
}
}
const CString CStrToOper::GetErrMsg(void)
{
static const CString errmsg[7] = {"no errors",
"missing left parentheses",
"missing right parentheses",
"devide by zero",
"unknown operator",
"unknown error",
"UNKNOWN ERROR ID"};
if(ErrId >= 0 && ErrId < 6)
return errmsg[ErrId];
else
return errmsg[6];
}
int CStrToOper::GetErrId(void)
{
return ErrId;
}
double CStrToOper::Calculate(int type, double x, double y)
{ // 雙目運(yùn)算符的具體運(yùn)算
if (type > 20 && type < 40) //處理雙目運(yùn)算
switch(type) { // '+' , '-' , '*' , '/' , '^'
case OPTR_ADD : return ( x + y );
case OPTR_SUBTRACT : return ( x - y );
case OPTR_MULTIPLY : return ( x * y );
case OPTR_DIVIDE :
if (y == 0.0)
ErrId=ERR_DIVIDEBYZERO;
else
return ( x / y );
break;
case OPTR_POWER : return (pow( x, y));
default : ErrId=ERR_UNKNOWNOPR; return 0.0;
}
else {
ErrId=ERR_UNKNOWNOPR;
return 0.0;
}
return 0.0;
}
double CStrToOper::Calculate(int type, double x)
{// 單目運(yùn)算符的具體運(yùn)算
static double (*fun[])(double)={sin, cos, tan, sqrt,
log10, log, fabs, asin, acos, atan, sinh,
cosh, tanh, exp}; //*fname[]對(duì)應(yīng)的C函數(shù)名
if(type>50) //函數(shù)運(yùn)算
return ((*fun[type-51])(x));
else {
ErrId=ERR_UNKNOWNOPR;
return 0.0;
}
return 0.0;
}
bool CStrToOper::IsNum(CString str,int thisposition)
{
if (isdigit(str.GetAt(thisposition))||(str.GetAt(thisposition)=='.')||(str.GetAt(thisposition)=='-')&&(!isdigit(str.GetAt(thisposition-1))))
return TRUE;
else return FALSE;
}
int CStrToOper::GetPreValue(CString str,int position,CString &str1)
{
int thisposition;
thisposition=position-1;
while (thisposition>0&&IsNum(str,thisposition))
{
thisposition--;
}
if (thisposition!=0)
thisposition++;
str1=str.Mid(thisposition,position-thisposition);
return thisposition;
}
int CStrToOper::GetNextValue(CString str,int position,CString &str2)
{
int thisposition=position+1;
while (IsNum(str,thisposition)&&thisposition<str.GetLength()-1)
{
thisposition++;
}
if (thisposition!=str.GetLength()-1)
thisposition--;
str2=str.Mid(position+1,thisposition-position);
return thisposition;
}
double CStrToOper::ValueCalculate(CString str)//對(duì)只有數(shù)值和操作符的表達(dá)式進(jìn)行計(jì)算
{
int flag=1;
int i;
int position;
int position1;
int position2;
int preposition;
int nextposition;
int OPTR_SELECT;
double tempresult;
CString str1;
CString str2;
CString strpre,strmid,strnext;
flag=(str.Find('^')!=-1);
while (flag) //處理最高級(jí)別^
{
position=str.Find('^');
preposition=GetPreValue(str,position,str1);
nextposition=GetNextValue(str,position,str2);
tempresult=Calculate(OPTR_POWER,atof(str1),atof(str2));
strpre=str.Left(preposition);
strmid.Format("%4.6f",tempresult);
strnext=str.Right(str.GetLength()-nextposition-1);
str=strpre+strmid+strnext;
flag=(str.Find('^')!=-1);
}
flag=((str.Find('*')!=-1)||(str.Find('/')!=-1));
while (flag) //處理次高級(jí)別*,/
{ position1=str.Find('*');
position2=str.Find('/');
if (((position1<position2)&&(position1!=-1))||(position2==-1))
{
position=position1;
OPTR_SELECT=OPTR_MULTIPLY;
}
else
{
position=position2;
OPTR_SELECT=OPTR_DIVIDE;
}
preposition=GetPreValue(str,position,str1);
nextposition=GetNextValue(str,position,str2);
tempresult=Calculate(OPTR_SELECT,atof(str1),atof(str2));
strpre=str.Left(preposition);
strmid.Format("%4.6f",tempresult);
strnext=str.Right(str.GetLength()-nextposition-1);
str=strpre+strmid+strnext;
flag=((str.Find('*')!=-1)||(str.Find('/')!=-1));
}
flag=((str.Find('+')!=-1)||(str.Find('-',1)!=-1));
i=0;
while (flag) //處理低級(jí)別+,-
{
position1=str.Find('+');
position2=str.Find('-',1);
i=position2+1;
if (((position1<position2)&&(position1!=-1))||(position2==-1))
{
position=position1;
OPTR_SELECT=OPTR_ADD;
}
else
{
position=position2;
OPTR_SELECT=OPTR_SUBTRACT;
}
preposition=GetPreValue(str,position,str1);
nextposition=GetNextValue(str,position,str2);
tempresult=Calculate(OPTR_SELECT,atof(str1),atof(str2));
strpre=str.Left(preposition);
strmid.Format("%4.6f",tempresult);
strnext=str.Right(str.GetLength()-nextposition-1);
str=strpre+strmid+strnext;
flag=(str.Find('+')!=-1)||(str.Find('-',1)!=-1);
}
tempresult=atof(str);
return tempresult;
}
BOOL CStrToOper::GetOperType(CString str,int leftParentese,int &count,int &type)
{ type=0;
count=3; //操作符長(zhǎng)度
CString strOpr;
while (count<6)
{
if (leftParentese-count<0) return FALSE;
else
{ strOpr=str.Mid(leftParentese-count,count);
if (strOpr=="sin")type=51;
if (strOpr=="cos")type=52;
if (strOpr=="tan")type=53;
if (strOpr=="sqrt")type=54;
if (strOpr=="log10")type=55;
if (strOpr=="log")type=56;
if (strOpr=="fabs")type=57;
if (strOpr=="asin")type=58;
if (strOpr=="acos")type=59;
if (strOpr=="atan")type=60;
if (strOpr=="sinh")type=61;
if (strOpr=="cosh")type=62;
if (strOpr=="tanh")type=63;
if (strOpr=="exp")type=64;
if (type!=0) return TRUE;
}
count++;
}
return FALSE;
}
CString CStrToOper::RemoveParentheses() //將表達(dá)式變成數(shù)值表達(dá)式
{
int flag,count=0,type;
int leftParenthese,rightParenthese;
CString str=Expression;
CString strpre,strmid,strnext;
flag=(str.Find(')')!=-1);
while (flag)
{
rightParenthese=str.Find(')');
leftParenthese=rightParenthese-1;
while (str.GetAt(leftParenthese)!='(')
{
leftParenthese--;
}
if (leftParenthese==0||!isalnum(str.GetAt(leftParenthese-1)))
{
strpre=str.Left(leftParenthese);
strmid.Format("%4.6f",ValueCalculate(str.Mid(leftParenthese+1,rightParenthese-leftParenthese-1)));
strnext=str.Right(str.GetLength()-rightParenthese-1);
}
else
{
if (GetOperType(str,leftParenthese,count,type))
{
strpre=str.Left(leftParenthese-count);
strmid.Format("%4.6f",Calculate(type,ValueCalculate(str.Mid(leftParenthese+1,rightParenthese-leftParenthese-1))));
strnext=str.Right(str.GetLength()-rightParenthese-1);
}
else
{
ErrId=ERR_UNKNOWNOPR;
break;
}
}
str=strpre+strmid+strnext;
flag=(str.Find(')')!=-1);
}
return str;
}
void CStrToOper::Computer()
{ CString strValue;
strValue=RemoveParentheses();
Result=ValueCalculate(strValue);
}
double CStrToOper::GetResult(void)
{ if (ErrId==0)
Computer();
return Result;
}
CStrToOper::~CStrToOper()
{
}
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號(hào)
Ctrl + =
減小字號(hào)
Ctrl + -