![]() |
Taschenrechner - String durchsuchen
Hallo liebe Community.
Wir haben in der Schule grade mit Delphi angefangen, und sollen nun einen Taschenrechner programmieren. Nun stehe ich allerdings vor dem Problem mit Punkt- vor Strichrechnung. Habe jetzt ein Label in dem der Gesamte Term steht der Berechnet werden soll also zB.: Zitat:
Ich selber Programmiere seit Jahren in PHP deswegen kam ich auch auf die Idee das so zu machen, dass ich am Ende den ganzen String nach den Operationszeichen durchsuche und dann jeweils die Zahl davor und dannach miteinander addiere, subtrahiere, multipliziere oder dividiere. Leider weiß ich nur nicht wie ich das in Delphi realisieren kann. Danke für die Hilfe. Tobias |
Re: Taschenrechner - String durchsuchen
Hmm, damit habe ich mich vor kurzem auch beschäftigt, ich weiß zwar nicht ob meine Lösung optimal ist, aber mein Prinzip war, dass ich es rekursiv löse.
Zuerst suchte ich nach dem + Wenn ich das gefunden habe sagt ich, dass es die beiden Teilstrings addieren soll. Die wurden natürlich wiederum von meiner Funktion zerlegt. Ich weiß jetzt nicht, ob ich es richtig erklärt habe, aber so in etwa habe ich es durchgeführt :wink: |
Re: Taschenrechner - String durchsuchen
Ja ich wollt ganz gerne die Funktion in Delphi wissen um dies zu realisieren x)
|
Re: Taschenrechner - String durchsuchen
Da gibt es meines Wissens keine, das musst du schon selbst realisieren :wink:
|
Re: Taschenrechner - String durchsuchen
Könnte mir dann bitte jemand nen Tipp geben wie?
Wie gesagt wir haben grade erst mit Delphi angefangen :( Danke Tobias |
Re: Taschenrechner - String durchsuchen
Hi und willkommen in der DP ;-)
Zitat:
Wenn du dich wirklich daran versuchen willst, dann musst du dir vorher genaue Gedanken machen, wie du das angehen willst. Da gibt es sicherlich mehrere Möglichkeiten, die man verfolgen kann, aber letzendlich musst du alles selber machen, Delphi nimmt dir da im ersten Moment nichts ab. Alternativ kannst du mal in der DP nach "Parser" suchen, da sollte sich inzwischen einiges finden lassen. mfg Edit: Hab gerade mal bei meinem Parser, den ich vor Kurzem geschrieben habe, nachgeschaut. Die Unit hat exakt 732 Zeilen (gut, der kann noch etwas mehr, wie z.B. Klammern, Funktionen, ...). Daran sieht man aber doch sehr deutlich, was da für eine Arbeit dahintersteckt. Edit2: Zu deiner Frage: Mit ![]() |
Re: Taschenrechner - String durchsuchen
Naja uns wurde halt gesagt wir sollen Punkt vor Strichrechnung beachten.
Auf die Idee mit dem String bin ich ja gekommen weil ichs von PHP her kannte. Vll könnte man das aber auch so realisieren, dass man immer ne Zahl speichert und dann jeweils das Rechenzeichen und dann nochmal die Zahl und das nächste Rechnezeichen. Also ich muss das nicht über die Methode machen dass ich den kompletten Term dann durchsuche. Es soll halt nur Punkt vor Strichrechnung beachtet werden. Wenns ne Möglichkeit gibt, die einfacher ist, nehm ich die gerne :) |
Re: Taschenrechner - String durchsuchen
Hast du schon meinen Edit in meinem oberen Post bemerkt?
Da hab ich nämlich einen Ansatz, mit dem man das relativ einfach lösen kann, genannt. Besorge dir erstmal die Stelle des ersten *-Zeichens in deinem String (Erklärung siehe oben). Wenn du das geschafft hast, dann kannst du dich an den nächsten Schritt wagen. |
Re: Taschenrechner - String durchsuchen
Delphi-Quellcode:
muh.caption := pos('+',term.caption);
Zitat:
|
Re: Taschenrechner - String durchsuchen
Schau mal in der Hilfe, was Pos zurückgibt, dann weißt Du auch, was Du falsch gemacht hast.
|
Re: Taschenrechner - String durchsuchen
ah ok inttostr() ^^
Danke, jetzt gibt er z.B. 6 zurück, und weiter? :) |
Re: Taschenrechner - String durchsuchen
Jetzt hast Du die Position, die Du im Copy()-Befehl angeben kannst ;)
|
Re: Taschenrechner - String durchsuchen
kenn den copy befehl noch net, danke ^^
//Edit: wie mach ich das denn dass er bis zum nächsten Zeichen und dem Zeichen davor macht? |
Re: Taschenrechner - String durchsuchen
Hmm komm echt noch nicht wirklich mit klar, wie krieg ich es hin dass er es bis zum nächsten Zeichen nur ausliest bzw halt zu dem zeichen davor?
|
Re: Taschenrechner - String durchsuchen
Der Copy()-Befehl hat 3 Parameter: den Ausgangsstring, Startposition in diesem und die Länge (nicht die Position), bis zu der kopiert werden soll. Bsp.:
Delphi-Quellcode:
Damit werden ab Position 1 5 Zeichen kopiert und in Substring zurückgegeben.
SubString := Copy(Ausgangsstring,1,5);
Ist doch eigentlich verständlich, wo hängt es denn? |
Re: Taschenrechner - String durchsuchen
Ja die Copy funktion hab ich ja jetzt verstanden.
Es hängt halt da wie ich es realisieren soll dass er zB aus 4-2*2+11-5 mit neu.caption := inttostr(pos('+',term.caption)); nur das 2+1 rausziehe. Weil bei copy muss ich ja denn ne gewisse Länge angeben. und es muss ja irgendwie sowas wie count() geben um die anzahl der Zeichen bis zum nächsten Operator (in dem Fall halt das -) auslesen zu können. Danke :) |
Re: Taschenrechner - String durchsuchen
Hallo, ich habe das auch mal für die Schule gemacht.
![]() Hier wird der Term in Rechenzeichen und Zahlen zerteilt und in eine Liste geschrieben: aus 12*2+3/2 wird dann 12 * 2 + 3 / 2 Dann wird diese Liste nach * und / durchsucht und die Zahlen davor und danach werden entsprechend ausgerechnet. In Zeile 2 gefunden : * Also 12*2 = 24 Liste sieht wie folgt aus: 24+3/2 Das macht man so lange, bis keine * und / mehr da sind, und macht das Ganze mit + und - . Wenn auch die alle weg sind, also alles ausgerechnet wurde, nimmt ,man dann die erste Zeile als Ergebnis. Liebe Grüße! |
Re: Taschenrechner - String durchsuchen
So als Tipp (weil ich grad keine Lust/Zeit hab alles nochmals zu sagen:
Such mal hier im Forum nach Matheparsern, denn es gibt da schon einige Threads, wo alles Nötige erklärt wird. z.B.: ![]() [edit] toll, da ist mir ja 'ne gewisse Person zuvorgekommen :lol: |
Re: Taschenrechner - String durchsuchen
Liste der Anhänge anzeigen (Anzahl: 1)
Ich habe die letzten Stunden mal ein bisschen probiert und steh nun vor einem Fehler, der mir völlig unlogisch erscheint.
Habe das Programm mal angehangen, wäre lieb, wenn das mal jemand durchgucken könnte. Die Fehlermeldung kommt z.B. wenn man 5+5+5+5-5 eingibt.↲↲Ah habe meinen fehler denke ich gefunden. Nämlich, dass er die zweite schleife noch nach der ersten abarbeitet. Gibt es sowas wie ne die-funktion wie in php auch in delphi? |
Re: Taschenrechner - String durchsuchen
"Die" dürte einer Exception entsprechen:
Delphi-Quellcode:
raise Exception.Create('hier die Fehlerbeschreibung');
|
Re: Taschenrechner - String durchsuchen
Liste der Anhänge anzeigen (Anzahl: 1)
Ah ich verzweifel grade wieder...
Bin jetzt soweit dass ich bei dem * angelangt bin. Aber irgendwie komm ich nicht weiter... der Taschenrechner soll ja dann halt abwarten was nach dem * eingegeben wird weil das ja vor dem + gerechnet werden muss.. Vielleicht hat ja einer Zeit und Lust mal rüberzugucken. Danke schonmal :) Tobias |
Re: Taschenrechner - String durchsuchen
"ganz einfach"
- du zerlegst den String erstmal in seine Einzelteile (Zahlen und Operatoren) - dann löst du nach und nach die Operatoren auf (also natürlich zuerst die * und danach erst die + ) - zum Auflösen jeweils "Zahl Operator Zahl" suchen dieses ausrechnen und gegen das Ergebnis austauschen |
Re: Taschenrechner - String durchsuchen
Dazu müsst ich ja das ganze meines wissens nach in nen Array schreiben (bei PHP zumindest).. leider haben wir noch nicht gelernt wie wir das mit Delphi machen in der Schule, sondern verändern nur die Eigenschaften von Labels und so..
|
Re: Taschenrechner - String durchsuchen
Du brauchst nicht unbedingt ein Array.
Eine TStringList ist da eh einfacher zu verwalten. Wie du den String zerlegst hast du ja schon. Nun brauchst du einfach nur den String zerlegen und erstmal in eine Stringliste einfügen (.Add). |
Re: Taschenrechner - String durchsuchen
also wenn ich zB
5+2-4*2+5 habe dann such ich also zuerst mit pos() nach dem * und müsste dann ja ne 6 zurückerhalten. aber woher weiß ich wieweit ich vor und zurückgehen muss? |
Re: Taschenrechner - String durchsuchen
Liste der Anhänge anzeigen (Anzahl: 1)
So ich hab mal fast den Ganzen Taschenrechner umgeschrieben :coder:
Weil sei mir net böse aber mit deinem Prinzip klappt das so nicht (soll net böse gemeint sein sondern nur eine feststellung :zwinker: ) Hab auch ein paar Kommentare dazugeschrieben. Ich schätze mal so müsstest du es hinbekommen ihn zu vervollständigen Hab jetzt als Beispiel mit +,-,* und / und mit Kommas auch getestet. Er errechnet es mir richtig. Hoffe du verstehst wie das Prinzip von mir ist. |
Re: Taschenrechner - String durchsuchen
Woah, um ehrlich zu sein seh ich da garnicht durch mit der Liste und so, denke das ist auch noch zu hoch für das Niveau wie wir den Taschenrechner machen sollen, weil wir haben ja mit Delphi grade erst angefangen.
Danke schonmal für die Hilfe, aber so kann ich das denk ich schlecht machen, weil wir ja soweit noch nicht sind =/ Muss ich wohl weiter mit meinem rumprobieren EDIT://
Delphi-Quellcode:
Habe jetzt das Problem dass wenn er im neo.caption nen '-' drin zu stehen hat, er irgendwas rechnet, aber nicht das was er soll... z.B. bei 5+5+5+5+5-6*3*(an der stelle bekommt er 126 raus und nicht 7 wie er eigentlich sollte).
if neo.caption = '*'
then begin ne.caption := floattostr(strtofloat(ne.caption)*strtofloat(display.text)); display.text := '0'; neo.caption := '*'; end else begin if nz1.caption = '' then begin nz1.Caption := display.text; no1.caption := '*'; display.text := '0'; end else begin nz2.caption := display.text; no2.caption := '*'; punkt.caption := floattostr(strtofloat(nz1.caption)*strtofloat(nz2.caption)); if neo.caption = '+' then begin ne.caption := floattostr(strtofloat(ne.caption)+strtofloat(punkt.caption)); nz1.caption := ''; nz2.caption := ''; no1.caption := ''; no2.caption := ''; neo.caption := '*'; end; if neo.caption = '-' then begin ne.caption := floattostr(strtofloat(ne.caption)-strtofloat(punkt.caption)); nz1.caption := ''; nz2.caption := ''; no1.caption := ''; no2.caption := ''; neo.caption := '*'; end; if neo.caption = '*' then begin ne.caption := floattostr(strtofloat(ne.caption)*strtofloat(punkt.caption)); nz1.caption := ''; nz2.caption := ''; no1.caption := ''; no2.caption := ''; neo.caption := '*'; end end end end; Find meinen Fehler aber nicht :( |
Re: Taschenrechner - String durchsuchen
Aso.....ups... :mrgreen:
Okay. Also ich hab durchgeschaut und ein Taschenrechner hört sich leicht an, aber in dem Umfang find ich ist es sehr sehr schwer mit einfachen Dingen wie Labeln. Ansteller meiner Liste kannste auch ein Memo benutzen und dan per Lines machen. Ist das gleiche Prinzip. Nur musste das die Codezeilen mit Assigned und Create von der Liste rausnehemn, da es sonst zu Fehlern kommt. :zwinker: Und nur mit If-Anweisungen oder so (weis net ob ihr while-Schleifen schon habt) wird es noch schwerer meiner Meinung nach. Aber IndexOf gibt es auch bei Memo.Lines :zwinker: Ist genau das gleiche. Meiner Meinung nach geht es ohne eine Schleife überhaupt nicht. Da man erstens, das stimmt mit einer Liste arbeiten muss und zweitens jeden Eintrag druchgehen muss und mit einer for..to..do Schleife wird es glaub ich auch schlecht funktionieren. Meiner Meinung nach kannst du dir ja das mal aufheben..vieleicht verstehst du dan später was ich gemacht hab und hilft dir dan später bei anderen Projekten :mrgreen: :zwinker: EDIT: Du warst schneller, ändert aber im Prinzip nichts an meine Antwort :mrgreen: |
Re: Taschenrechner - String durchsuchen
Vielleicht kannst du aber den Fehler in meinem Code finden :P
Also If-Schleifen sind die einzigen die wir bisher hatten. While und for schleifen kenn ich aber aus PHP und die werden denk ich in Delphi nicht groß anders sein. IndexOf sagt mir jetzt garnichts... Mit Memos haben wir auch noch nicht gearbeitet. |
Re: Taschenrechner - String durchsuchen
Noch ein Hinweis: Im Gegensatz zu PHP beginnt in Delphi die Zeichenzählung in einem String nicht mit 0, sondern mit 1. :zwinker:
Die Lösung, das ganze rekursiv zu machen, ist auf gar keinen Fall optimal, aber am einfachsten. Ich verweise mal hierauf: ![]() Und auch in Delphi kannst du ein einzelnes Zeichen mit s[i] auslesen, aber wie gesagt, Zählung beginnt bei 1. |
Re: Taschenrechner - String durchsuchen
Zitat:
|
Re: Taschenrechner - String durchsuchen
So wie ich das sehe geht es nicht ohne eine Liste also Memo. Du musst den gesammten Term (also alles) sehen und dan auswerten wo die * und wo die + sind.
Dann nach und nach "auflösen" d.h. bei z.b. 5+5*5; So d.h. du musst erst mal alles sammeln, wenn ihr aber es in Schritten machen müsst, wir das meine Meinung nach wie schno gesagt nicht gehen. Gut mal ausgegangen du hast jetzt in einem Memo folgendes stehen:
Code:
So jetzt kannst du anfangen zu berechnen.
5
+ 5 * 5 Du musst jetzt wissen wo das * ist wegen Punkt vor Strich also in welcher Zeile. Dies bekommt man mit IndexOf von Memo.Lines (Lines ist die Liste, die ich in meinem Beispiel erstellt hatte) Damit bekommt du den Index das ist die Zeile. Diese merkst du dir dann. Mit dme Index -1 bekommst du dan die Zeile vor dem * also die Zahl. Und mit Index +1 die Zahl danach. Da String in Float umwandeln und berechnen lassen. Der Hacken ist aber jetzt, dass es sein kann das ja noch ein * oder so drinne ist.Deshalb eine Schleife, um alle * und so erstmal rauszufiltern. Danach das gleiche mit + und so. Also ohne eine Schleife wirst du wohl um es einfachzuhalten nicht darum kommen :angel: Und Jakob : Meiner Meinung nach ist deine Lösung noch komplizierter :mrgreen: Nicht böse gemeint nur dies ist noch komplexer mit Prozedure und Funktionen und was weis ich nicht alles :zwinker: |
Re: Taschenrechner - String durchsuchen
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! |
Alle Zeitangaben in WEZ +1. Es ist jetzt 08:45 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz