Das hier ist ein Parser, der keine Klammern berechnen kann, aber dennoch Punkt vor Strich beachtet.
Delphi-Quellcode:
function TForm1.Rechnen(
Const Term:
string):
String;
Var SL: TStringList;
//Das ist eine Variable für die Liste, in die der Term zerlegt wird.
i: Integer;
//Wird hier als Variable für diverse Schleifen benutzt
S:
string;
//Ist in der folgenden Funktion der Term
Begin
{Falls das erste Zeichen ein Rechenzeichen wie + oder - ist, so wird eine Null eingefügt,
um die Rechnung fortzusetzen (Beim Rechnen würde sonst ein Fehler auftreten)}
S:=Term;
//Term wird in S kopiert
case S[1]
of
'
+','
-':
begin
insert('
0',S,1);
end;
{Die Rechenzeichen am Anfang des Terms * und / werden gelöscht und somit ignoriert}
'
*','
/':
begin
Delete(S,1,1);
end;
end;
//Rechenzeichen am Ende werden gelöscht
case S[Length(S)]
of
'
+','
-','
*','
/':
begin
Delete(S,Length(S),1);
end;
end;
SL := TStringList.Create;
//Die Liste wird initialisiert.
Try
Try
SL.Add('
');
//Es wird eine neue Zeile hinzugefügt.
For i := 1
to Length(S)
do //Schleife über alle Zeichen des Terms
Case S[i]
of
'
0'..'
9', '
,', '
.':
Begin //Wenn Zeichen an Position i eine Zahl oder ein Komma ist,
SL[SL.Count - 1] := SL[SL.Count - 1] + S[i];
//Dann füge es an eine schon bestehende Zahl an
End;
'
*', '
/', '
+', '
-':
Begin //Rechenzeichen werden in eine eigene Zeile geschrieben
If SL[SL.Count - 1] = '
'
Then Begin
//Eventuell eine leere Zeile löschen (Wenn zwei Rechenzeichen hintereinander stehen
SL.Delete(SL.Count - 1);
End;
SL.Add(S[i]);
//Rechenzeichen hinzufügen
SL.Add('
');
//Zeilenumbruch einfügen (Damit die nächste Zahl eine eigene Zeile hat)
End;
Else Raise Exception.CreateFmt('
Ungültiges Zeichen "%s" gefunden.', [S[i]]);
End;
{Ab hier wird gerechnet}
begin
begin
i:=0;
//Wir beginnen wieder am Anfang
while i < SL.Count
do
begin
if SL[i]='
*'
then //Mal wird berechnet
begin
SL[i-1]:=(FloatToStr(StrToFloat(SL[i-1])*StrToFloat(SL[i+1])));
{Zahl vor und nach dem * werden multipliziert und in die Zeile der ersten Zahl geschrieben???}
SL.Delete(i);
{Jetzt soll die Zeile des Operators gelöscht werden}
SL.Delete(i);
{und die der zweiten Zahl}
{etwas wurde gefunden - fange von vorn an}
i := i-1;
end
else
if SL[i]='
/'
then //Geteilt rechnen
begin
SL[i-1]:=(FloatToStr(StrToFloat(SL[i-1])/StrToFloat(SL[i+1])));
SL.Delete(i);
SL.Delete(i);
i := i-1;
end
else
i := i + 1;
end;
i:=0;
//Da es jetzt keine Punktrechnung mehr gibt, fangen wir wieder von vorne an und machen das Ganze mit + u.-
while i < SL.Count
do
begin
if SL[i]='
+'
then
begin
SL[i-1]:=(FloatToStr(StrToFloat(SL[i-1])+StrToFloat(SL[i+1])));
{Zahl vor und nach dem * werden multipliziert und in die Zeile der ersten Zahl geschrieben???}
SL.Delete(i);
{Jetzt soll die Zeile des Operators gelöscht werden}
SL.Delete(i);
{und die der zweiten Zahl}
{etwas wurde gefunden - fange von vorn an}
i := i-1;
end
else
if SL[i]='
-'
then
begin
SL[i-1]:=(FloatToStr(StrToFloat(SL[i-1])-StrToFloat(SL[i+1])));
SL.Delete(i);
SL.Delete(i);
i := i-1;
end
else
i := i + 1;
end;
end;
end;
Finally
Result := SL[0];
//Am Ende ist dann nur noch eine Zeile übrig, die ist das Ergebnis
end;
Finally
SL.Free;
//Speicher der Liste wieder freigeben
End;
end;
Der Aufruf für soetwas wäre dann z.B.
Edit1.text:=Rechnen(Edit2.text);
Der Term aus Edit2 wird berechnet und das Ergebnis wird in Edit1 ausgegeben
Das Ganze ist jetzt zwar funktionsfähig, versuch aber mal deinen eigenen zu basteln...
Liebe Grüße!