需要该这段程序,但其中有些地方不知该怎么改 ,请教各位了。
double Calc::Run(char* buffer)
{ TStringList* tokens = new TStringList();
char buf[CALC_MAXBUFFER];
AnsiString nowT;
int pos; //标记链表中的位置
int r;
TStringList *opnd = new TStringList();
TStringList *oper = new TStringList();
AnsiString a,b,x,y,z;
bool operLevel3 = true; //以上一段TstringList部分不知该如何改 isError=false;
strcpy(buf,buffer);
r = getToken(buf,tokens);
if(r != -1)
{
SetError("Expression syntax error.");
return 0.0;
}
tokens->Add("$");
pos = 0; opnd->Add("0");
oper->Add("$"); while(pos<(tokens->Count))
{
nowT=tokens->Strings[pos];
pos++;
nowT.TrimLeft();
nowT.TrimRight();
nowT = nowT.LowerCase(); if(nowT == "e") nowT="2.718281828";
if(nowT == "pi") nowT="3.1415926535897932384";
if(nowT == "ans") nowT =AnsiString(m_Ans);
if(nowT == "mr") nowT =AnsiString(m_Memory);
if((nowT.SubString(1,1) == "#")&&(nowT.SubString(nowT.Length(),1) == "#"))
if(!ProcVariable(nowT))
{
SetError("System variable not defined.");
return 0.0;
}
if(nowT.Pos('.')!=0)
{ // It's a number.
opnd->Add(nowT);
operLevel3 = false;
}
else{ // Now we get a operator.
//a = oper.GetTail();
if(nowT == "("){
oper->Add(nowT);
}
else{
if(nowT == ")")
{ // So we just push the stacks until we encountered "("
a = oper->Strings[oper->Count-1];
oper->Delete(oper->Count-1);
while(a != "(")
{
if(!operate(opnd,a))
{
SetError("Math operation error, perhaps the expression syntax.");
return 0.0;
}
a = oper->Strings[oper->Count-1];
oper->Delete(oper->Count-1);
}
}
else{
a = oper->Strings[oper->Count-1]; // Not push, just look at it.
if(getPrior(a.c_str()) < getPrior(nowT.c_str())){
if((operLevel3)&&(nowT == '-')) nowT = "minus"; // special treat to the prefix '-'
if((operLevel3)&&(nowT == '+')) nowT = "positive"; // special treat to the prefix '+'
oper->Add(nowT);
}
else{ // We can calculate it until the prior return to be >
a = oper->Strings[oper->Count-1];
oper->Delete(oper->Count-1);
while((getPrior(a.c_str()) >= getPrior(nowT.c_str())) && (!((a == "$")&&(nowT == "$"))))
{
if(!operate(opnd,a))
{
SetError("Math operation error, perhaps the expression syntax.");
return 0.0;
}
a = oper->Strings[oper->Count-1];
oper->Delete(oper->Count-1);
}
if((a == "$")&&(nowT == "$")) break;
else{
oper->Add(a);
oper->Add(nowT);
}
}
}
}
operLevel3 = true; // we are encountering a symbol, so if we goon getting this, it'll be treated especially.
}
} m_Ans=atof((LPCTSTR)((opnd->Strings[opnd->Count-1]).c_str()));
opnd->Clear();
oper->Clear();
tokens->Clear();
return m_Ans;
}int Calc::getToken(char *buffer,TStringList *result){
int lastToken = CALC_NUM;
bool haveDot = false, isVar = false;
unsigned int nowP=0,nowNum=0,nowSym=0;
char numBuf[CALC_MAXBUFFER]="",symBuf[CALC_MAXBUFFER]=""; while(nowP<strlen(buffer)){
if(buffer[nowP] != ' '){
if(((buffer[nowP]>='0'&&buffer[nowP]<='9')||(buffer[nowP]=='.'))&&(!isVar)){
if(buffer[nowP]=='.')
if(haveDot==true) return(nowP);
else haveDot=true;
numBuf[nowNum]=buffer[nowP];
nowNum++;
if(lastToken!=CALC_NUM&&nowSym!=0){
symBuf[nowSym]='\0';
result->Add(symBuf);
strcpy(symBuf,"");nowSym=0;
}
lastToken=CALC_NUM;
}
else{
if(lastToken==CALC_NUM&&nowNum!=0){
if(!haveDot){ numBuf[nowNum]='.';numBuf[nowNum+1]='\0';}
else numBuf[nowNum]='\0';
result->Add(numBuf);
strcpy(numBuf,"");nowNum=0;haveDot=false;
}
symBuf[nowSym]=buffer[nowP];
nowSym++;
if(buffer[nowP] == '#') isVar = true;
if(checkSym(symBuf,nowSym)){
symBuf[nowSym]='\0';
result->Add(symBuf);
strcpy(symBuf,"");nowSym=0;
if(isVar) isVar = false;
}
lastToken=CALC_SYM;
}
}
nowP++;
} if(lastToken==CALC_NUM&&nowNum!=0){
if(!haveDot){ numBuf[nowNum]='.';numBuf[nowNum+1]='\0';}
else numBuf[nowNum]='\0';
result->Add(numBuf);
strcpy(numBuf,"");nowNum=0;haveDot=false;
}
if(lastToken==CALC_SYM&&nowSym!=0){
symBuf[nowSym]='\0';
result->Add(symBuf);
strcpy(symBuf,"");nowSym=0;
}
return(-1);
}
double Calc::Run(char* buffer)
{ TStringList* tokens = new TStringList();
char buf[CALC_MAXBUFFER];
AnsiString nowT;
int pos; //标记链表中的位置
int r;
TStringList *opnd = new TStringList();
TStringList *oper = new TStringList();
AnsiString a,b,x,y,z;
bool operLevel3 = true; //以上一段TstringList部分不知该如何改 isError=false;
strcpy(buf,buffer);
r = getToken(buf,tokens);
if(r != -1)
{
SetError("Expression syntax error.");
return 0.0;
}
tokens->Add("$");
pos = 0; opnd->Add("0");
oper->Add("$"); while(pos<(tokens->Count))
{
nowT=tokens->Strings[pos];
pos++;
nowT.TrimLeft();
nowT.TrimRight();
nowT = nowT.LowerCase(); if(nowT == "e") nowT="2.718281828";
if(nowT == "pi") nowT="3.1415926535897932384";
if(nowT == "ans") nowT =AnsiString(m_Ans);
if(nowT == "mr") nowT =AnsiString(m_Memory);
if((nowT.SubString(1,1) == "#")&&(nowT.SubString(nowT.Length(),1) == "#"))
if(!ProcVariable(nowT))
{
SetError("System variable not defined.");
return 0.0;
}
if(nowT.Pos('.')!=0)
{ // It's a number.
opnd->Add(nowT);
operLevel3 = false;
}
else{ // Now we get a operator.
//a = oper.GetTail();
if(nowT == "("){
oper->Add(nowT);
}
else{
if(nowT == ")")
{ // So we just push the stacks until we encountered "("
a = oper->Strings[oper->Count-1];
oper->Delete(oper->Count-1);
while(a != "(")
{
if(!operate(opnd,a))
{
SetError("Math operation error, perhaps the expression syntax.");
return 0.0;
}
a = oper->Strings[oper->Count-1];
oper->Delete(oper->Count-1);
}
}
else{
a = oper->Strings[oper->Count-1]; // Not push, just look at it.
if(getPrior(a.c_str()) < getPrior(nowT.c_str())){
if((operLevel3)&&(nowT == '-')) nowT = "minus"; // special treat to the prefix '-'
if((operLevel3)&&(nowT == '+')) nowT = "positive"; // special treat to the prefix '+'
oper->Add(nowT);
}
else{ // We can calculate it until the prior return to be >
a = oper->Strings[oper->Count-1];
oper->Delete(oper->Count-1);
while((getPrior(a.c_str()) >= getPrior(nowT.c_str())) && (!((a == "$")&&(nowT == "$"))))
{
if(!operate(opnd,a))
{
SetError("Math operation error, perhaps the expression syntax.");
return 0.0;
}
a = oper->Strings[oper->Count-1];
oper->Delete(oper->Count-1);
}
if((a == "$")&&(nowT == "$")) break;
else{
oper->Add(a);
oper->Add(nowT);
}
}
}
}
operLevel3 = true; // we are encountering a symbol, so if we goon getting this, it'll be treated especially.
}
} m_Ans=atof((LPCTSTR)((opnd->Strings[opnd->Count-1]).c_str()));
opnd->Clear();
oper->Clear();
tokens->Clear();
return m_Ans;
}int Calc::getToken(char *buffer,TStringList *result){
int lastToken = CALC_NUM;
bool haveDot = false, isVar = false;
unsigned int nowP=0,nowNum=0,nowSym=0;
char numBuf[CALC_MAXBUFFER]="",symBuf[CALC_MAXBUFFER]=""; while(nowP<strlen(buffer)){
if(buffer[nowP] != ' '){
if(((buffer[nowP]>='0'&&buffer[nowP]<='9')||(buffer[nowP]=='.'))&&(!isVar)){
if(buffer[nowP]=='.')
if(haveDot==true) return(nowP);
else haveDot=true;
numBuf[nowNum]=buffer[nowP];
nowNum++;
if(lastToken!=CALC_NUM&&nowSym!=0){
symBuf[nowSym]='\0';
result->Add(symBuf);
strcpy(symBuf,"");nowSym=0;
}
lastToken=CALC_NUM;
}
else{
if(lastToken==CALC_NUM&&nowNum!=0){
if(!haveDot){ numBuf[nowNum]='.';numBuf[nowNum+1]='\0';}
else numBuf[nowNum]='\0';
result->Add(numBuf);
strcpy(numBuf,"");nowNum=0;haveDot=false;
}
symBuf[nowSym]=buffer[nowP];
nowSym++;
if(buffer[nowP] == '#') isVar = true;
if(checkSym(symBuf,nowSym)){
symBuf[nowSym]='\0';
result->Add(symBuf);
strcpy(symBuf,"");nowSym=0;
if(isVar) isVar = false;
}
lastToken=CALC_SYM;
}
}
nowP++;
} if(lastToken==CALC_NUM&&nowNum!=0){
if(!haveDot){ numBuf[nowNum]='.';numBuf[nowNum+1]='\0';}
else numBuf[nowNum]='\0';
result->Add(numBuf);
strcpy(numBuf,"");nowNum=0;haveDot=false;
}
if(lastToken==CALC_SYM&&nowSym!=0){
symBuf[nowSym]='\0';
result->Add(symBuf);
strcpy(symBuf,"");nowSym=0;
}
return(-1);
}
解决方案 »
- 如何把选中的单选按钮值插入表中
- WM_DEVICECHANGE消息处理的问题
- 每次执行自定义类的构造函数时出错
- 我想做一个统计报表?如何做比较简单?
- delphi 2005调用vb编的程序怎么做呀,急急急!!!在线等!!!
- 急!在线等待!!请教高手如何用流的方式导入导出excel
- 请问如果在用dbnavigator控制记录添加时,如果手动中止数据添加动作???
- 在DELPHI如何让窗口最小化到系统托盘呢?
- 怎样在DBGRID相对应的字段中嵌入如下的控件 dbcombobox1 DBLookUpComboBox DBmemo,只要提代码都给分
- 关于日志实现的问题?
- 怎么申请一个2维数组例如a[60000][4],我直接申请静态的溢出了
- 怎么让下拉框只显示自定义的几种颜色?
list : TStringList;
begin
list := TStringList.Create;
var
tokens: TStringList;
buf: Array[0..CALC_MAXBUFFER-1] of AnsiChar;
nowT: AnsiString;
pos: Integer; //标记链表中的位置
r: Integer;
opnd: TStringList;
oper: TStringList;
a,b,x,y,z: AnsiString;
operLevel3: Boolean; //以上一段TstringList部分不知该如何改
begin
tokens := TStringList.Create();
opnd := TStringList.Create();
oper := TStringList.Create();
operLevel3 := true;
isError := false;
StrPCopy(buf,buffer);
Result := 0.0;
r := getToken(buf,tokens);
if(r <> -1) then
begin
SetError('Expression syntax error.');
Exit;
end;
tokens.Add('$');
pos := 0; opnd.Add('0');
oper.Add('$'); while(pos <(tokens.Count)) do
begin
nowT:=tokens.Strings[pos];
Inc(pos);
//nowT := TrimLeft(nowT);
//nowT := TrimRight(nowT);
nowT := Trim(nowT);
nowT := LowerCase(nowT); if(nowT = 'e') then nowT:='2.718281828';
if(nowT = 'pi') then nowT:='3.1415926535897932384';
if(nowT = 'ans') then nowT := AnsiString(m_Ans);
if(nowT = 'mr') then nowT :=AnsiString(m_Memory);
if((Copy(nowT,1,1) = '#') and (Copy(nowT,Length(nowT),1) = '#')) then
if Not (ProcVariable(nowT)) then begin
SetError('System variable not defined.');
Exit;
end;
if(AnsiPos('.', nowT)<>0) then
begin// It's a number.
opnd.Add(nowT);
operLevel3 := false;
end else begin // Now we get a operator.
//a = oper.GetTail();
if(nowT = '(') then begin
oper.Add(nowT);
end else begin
if(nowT = ')') then
begin // So we just push the stacks until we encountered "("
a := oper.Strings[oper.Count-1];
oper.Delete(oper.Count-1);
while(a <> '(') do
begin
if Not (operate(opnd,a)) then
begin
SetError('Math operation error, perhaps the expression syntax.');
Exit;
end; a := oper.Strings[oper.Count-1];
oper.Delete(oper.Count-1);
end;
end else begin
a := oper.Strings[oper.Count-1]; // Not push, just look at it.
if(getPrior(PAnsiChar(a)) < getPrior(PAnsiChar(nowT))) then begin
if((operLevel3) and (nowT = '-')) then nowT := 'minus'; // special treat to the prefix '-'
if((operLevel3) and (nowT = '+')) then nowT := 'positive'; // special treat to the prefix '+'
oper.Add(nowT);
end else begin // We can calculate it until the prior return to be >
a := oper.Strings[oper.Count-1];
oper.Delete(oper.Count-1);
while((getPrior(PAnsiChar(a)) >= getPrior(PAnsiChar(nowT))) and (not ((a = '$') and (nowT = '$')))) do
begin
if( not operate(opnd,a)) then
begin
SetError('Math operation error, perhaps the expression syntax.');
Exit;
end;
a := oper.Strings[oper.Count-1];
oper.Delete(oper.Count-1);
end; if((a = '$') and (nowT = '$')) then break
else begin
oper.Add(a);
oper.Add(nowT);
end;
end;
end;
end;
operLevel3 := true; // we are encountering a symbol, so if we goon getting this, it'll be treated especially.
end;
end; m_Ans:=strtofloat(opnd.Strings[opnd.Count-1]);
opnd.Clear();
oper.Clear();
tokens.Clear();
Result := m_Ans;
end;function Calc.getToken(buffer: PAnsiChar; result: TStringList): Integer;
var
lastToken: Integer;
haveDot, isVar: Boolean;
nowP,nowNum, nowSym: LongWord;
numBuf: Array[0..CALC_MAXBUFFER-1] of AnsiChar;
symBuf: Array[0..CALC_MAXBUFFER-1] of AnsiChar;
begin
lastToken := CALC_NUM;
haveDot := false;
isVar := false;
nowP:=0;
nowNum:=0;
nowSym:=0;
fillchar( numBuf, sizeof(numBuf), 0);
fillchar( symBuf, sizeof(symBuf), 0); while(nowP <strlen(buffer)) do begin
if(buffer[nowP] <> ' ') then begin
if((((buffer[nowP]>='0') and (buffer[nowP] <='9')) or (buffer[nowP]='.')) and (Not isVar)) then begin
if(buffer[nowP]='.') then
if(haveDot=true) then begin
Result := (nowP);
Exit;
end
else haveDot:=true;
numBuf[nowNum]:=buffer[nowP];
Inc(nowNum);
if(lastTokenM<>CALC_NUM) and (nowSym<>0) then begin
symBuf[nowSym]:=#0;
result.Add(symBuf);
//strcpy(symBuf,"");
fillchar(symBuf,sizeof(symBuf),0);
nowSym:=0;
end;
lastToken:=CALC_NUM;
end else begin
if(lastToken=CALC_NUM) and (nowNum<>0) then Begin
if(not haveDot) then begin
numBuf[nowNum]:='.';
numBuf[nowNum+1]:=#0;
end else numBuf[nowNum]:=#0;
result.Add(numBuf);
fillchar(numBuf,sizeof(numBuf),0);
nowNum:=0;
haveDot:=false;
End;
symBuf[nowSym]:=buffer[nowP];
Inc(nowSym);
if(buffer[nowP] = '#') then isVar := true;
if(checkSym(symBuf,nowSym)) then begin
symBuf[nowSym]=#0;
result.Add(symBuf);
fillchar(symBuf,sizeof(symBuf),0);
nowSym:=0;
if(isVar)then isVar := false;
end;
lastToken:=CALC_SYM;
end;
end;
Inc(nowP);
end; if(lastToken=CALC_NUM) and (nowNum<>0) then begin
if(Not haveDot) then begin
numBuf[nowNum]:='.';
numBuf[nowNum+1]:=#0;
end else numBuf[nowNum]:=#0;
result.Add(numBuf);
fillchar(numBuf,sizeof(numBuf),0);
nowNum:=0;
haveDot:=false;
end;
if(lastToken=CALC_SYM) and (nowSym<>0) then begin
symBuf[nowSym]:=#0;
result.Add(symBuf);
fillchar(symBuf,sizeof(symBuf),0);
nowSym:=0;
end;
Result :=(-1);
end;