Ergebnis 1 bis 16 von 16

Thema: Taschenrechner mit Delphi

  1. #1

    Taschenrechner mit Delphi

    Hallo.
    So, ich bin nun kurzerhand zu euch gestoßen, weil ich ein dickes Problem mit Delphi habe. ^^"
    Also, wir müssen einen Taschenrechner entwerfen. Gut und schön.
    Wir sollen mit Strings arbeiten, die wir dann mit StrtoFloat umwandeln.
    So, nun aber mein Problem:
    Ich habe so wirklich keine Ahnung wie ich anfangen soll.
    Einen kleinen Teil des Codes habe ich bereits geschafft, das die Zahlen angezeigt werden. Allerdings wird mir bei den Rechenoperationen schwindelig.
    Wir sollen insgesamt folgende Operationen durchführen können:
    + (plus)
    - (minus)
    * (mal)
    / (geteilt)
    = (gleich)
    Und sämtliche Zahlen, also auch Kommazahlen.
    Hier der bereits angefangene Code:
    Code:
    unit Unit1;
    
    interface
    
    uses
      Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
      Dialogs, StdCtrls;
    
    type
      TTaschenrechner = class(TForm)
        Display: TEdit;
        Btn7: TButton;
        Btn8: TButton;
        Btn9: TButton;
        Btn6: TButton;
        Btn5: TButton;
        Btn4: TButton;
        Btn1: TButton;
        Btn2: TButton;
        Btn3: TButton;
        Btn0: TButton;
        Btncomma: TButton;
        BtnOut: TButton;
        Btnplus: TButton;
        Btnminus: TButton;
        Btnmal: TButton;
        Btndivid: TButton;
        procedure Btn1Click(Sender: TObject);
        procedure Btn2Click(Sender: TObject);
        procedure Btn3Click(Sender: TObject);
        procedure Btn4Click(Sender: TObject);
        procedure Btn5Click(Sender: TObject);
        procedure Btn6Click(Sender: TObject);
        procedure Btn7Click(Sender: TObject);
        procedure Btn8Click(Sender: TObject);
        procedure Btn9Click(Sender: TObject);
        procedure Btn0Click(Sender: TObject);
        procedure BtncommaClick(Sender: TObject);
      private
        { Private declarations }
      public
        { Public declarations }
      end;
    
    var
      Taschenrechner: TTaschenrechner;
    
    implementation
    
    {$R *.dfm}
    
    procedure TTaschenrechner.Btn1Click(Sender: TObject);
    begin
      Display.Text := Display.Text+'1';
    
    end;
    
    procedure TTaschenrechner.Btn2Click(Sender: TObject);
    begin
      Display.Text := Display.Text+'2';
    
      end;
    
    procedure TTaschenrechner.Btn3Click(Sender: TObject);
    begin
      Display.Text := Display.Text+'3';
    
    end;
    
    procedure TTaschenrechner.Btn4Click(Sender: TObject);
    begin
      Display.Text := Display.Text+'4';
    
    end;
    
    procedure TTaschenrechner.Btn5Click(Sender: TObject);
    begin
      Display.Text := Display.Text+'5';
    
    end;
    
    procedure TTaschenrechner.Btn6Click(Sender: TObject);
    begin
      Display.Text := Display.Text+'6';
    
    end;
    
    procedure TTaschenrechner.Btn7Click(Sender: TObject);
    begin
      Display.Text := Display.Text+'7';
    
    end;
    
    procedure TTaschenrechner.Btn8Click(Sender: TObject);
    begin
      Display.Text := Display.Text+'8';
    
    end;
    
    procedure TTaschenrechner.Btn9Click(Sender: TObject);
    begin
      Display.Text := Display.Text+'9';
    
    end;
    
    procedure TTaschenrechner.Btn0Click(Sender: TObject);
    begin
      Display.Text := Display.Text+'0';
    
    end;
    
    procedure TTaschenrechner.BtncommaClick(Sender: TObject);
    begin
      Display.Text := Display.Text+',';
      
    end;
    
    end.
    Wäre nett wenn das mir jemand verständlich erklären könnte. ^^
    Danke!

  2. #2
    Und ihr habt das einfach so aufbekommen, ohne Erklärungen?
    Egal. ^^

    Also, bisher hast du ja nur mit Strings (also Texten) gearbeitet. (Eben dem Displaytext noch eine Zahl (als Text) hinzugefügt.)
    Wenn du nun jedoch mit Zahlen rechnen möchtest, musst das dem Computer ja auch sagen. Logisch, oder? ^^
    Variable_1 := Variable_2 + Variable_3;
    Mit diesem Code könntest du, wie bei deinem bisherigen Quellcode, einer Stringvariable (hier Display.Text) einen neuen Wert zuweisen, der auch aus Texten besteht, oder du könntest wirklich 'rechnen' - der einzige Unterschied liegt im Typ der Variablen.
    '5' + '7' ist also, da es durch die Hochkommatas Zeichen sind, und als Text behandelt wird, am Ende '57'.
    5 + 7 jedoch ist, da es ohne Hochkommatas als Zahlen behandelt wird (genauer: Integer-Zahlen), 12.

    Um nun deinem Delphi zu sagen, dass es mit den Zahlen doch bitte rechnen soll, musst du irgendwo deine Zahlen hernehmen.
    In deinem Fall würdest du die Zahlen aus deiner Display-Komponente nehmen, denn da hast du sie ja vorher bereits durch die Buttonklicks reingeschrieben.
    (Ich würde dir hierfür übrigens empfehlen, am Anfang mit mehreren Edit-Komponenten zu arbeiten, damit du einen ersten Summanden und einen zweiten Summanden klar unterteilt in zwei verschiedenen Feldern hast. Man kann auch alles aus einem Feld auslesen (also Zahlen, Rechenzeichen etc.), aber das wäre recht umständlich (und ich bin da grad zu faul, dir das alles vorzubeten ^^). *g*)

    Sagen wir also mal, du hast jetzt in Display1 deinen ersten Summanden, und in Display2 deinen zweiten.
    Du musst nun zunächst dir überlegen, wo du das Ergebnis der Rechnung ausgeben möchtest. (Beispielsweise nehme ich mal eine Label-Komponente.)
    Bei dem Label musst du in die Eigenschaft Caption schreiben, anstatt in die Eigenschaft Text...
    Also:
    Code:
    Label.Caption := irgendwas;
    So, dieses irgendwas wird jetzt bestimmt. ^^
    Code:
    Label.Caption := Display1.Text + Display2.Text;
    Das funktioniert zwar ohne Fehlermeldung, aber es ist nicht das, was wir wollen: Aus 5 und 7 würde hierbei nur wieder 57 werden, da Delphi ja merkt, dass man nur Strings, also Texte, zusammenfügt - und nicht Zahlen.
    Die Strings müssen also zunächst in Zahlen umgewandelt werden - mit deiner tollen StrtoFloat-Funktion. ^^
    Code:
    Label.Caption := StrtoFloat(Display1.Text) + StrtoFloat(Display2.Text);
    Dieser Code ist schon fast fertig, aber leider gibt Delphi nun eine Fehlermeldung aus. Wieso?
    Rechts hast nun die Texte in Zahlen umgewandelt, und Delphi also gesagt, dass es wirklich mit richtigen echten Zahlen rechnen soll (5 + 7 = 12 \o/ ).
    Aber links steht immernoch eine String-Variable (Eben das Label.Caption.), und deswegen kommt es zu einem Typfehler - es muss links und rechts einer Zuweisung ( := ) immer der gleiche Variablentyp stehen.

    Doch komm jetzt nicht auf die geniale Idee, einfach
    Code:
    StrtoFloat(Label.Caption) := StrtoFloat(Display1.Text) + StrtoFloat(Display2.Text);
    zu schreiben. ^^
    Auf der linken Seite einer Zuweisung darf niemals eine Typumwandlung durchgeführt werden, sondern nur auf der Rechten Seite. (Kannst es ja ausprobieren, also zumindest mein Delphi liefert da eine saftige Fehlermeldung. ^^'' )
    Um also den Post noch halbwegs kurz zu halten, hier die (nun endlich) richtige Quellcodezeile:
    Code:
    Label.Caption := FloattoStr(StrtoFloat(Display1.Text) + StrtoFloat(Display2.Text));
    Du hast also zwei Textwerte (Strings eben) zunächst in Zahlen umgewandelt, dann addiert, und dann wieder zurück in Texte umgewandelt. Diese werden dann über Label.Caption ausgegeben. \o/
    Die fertige procedure wäre dann also beispielsweise:
    Code:
    procedure TTaschenrechner.BtnplusClick(Sender: TObject);
    begin 
    Label.Caption := FloattoStr(StrtoFloat(Display1.Text) + StrtoFloat(Display2.Text)); 
    end;
    So.
    Wie du das ganze nun für die anderen Rechenarten machen kannst, müsstest du selbst herausfinden können. *g*
    Wenn es Fragen, Korrekturen oder sonstewas gibt, frag ruhig, ich tue alles, um mich von meinen Hausaufgaben abzulenken. xD

    Edit an den da unter mir:
    Ja klar geht das, 'türlich.
    Aber ich glaube nicht, dass juli.an von deinem Code etwas verstanden hat. (Nichts gegen dich, wenn doch, dann hab ich dich einfach falsch eingeschätzt. ^^'')
    Und deswegen habe ich ihm halt die einfachste Methode erklärt, und zwar so, wie ich zumindest es auch wirklich verstehen würde...
    Wenn man sich bereits mit Delphi auskennt, ist dein Code sicherlich toll, aber für einen Anfänger eher nicht hilfreich. *g*
    (Außerdem - wenn du es schon 'richtig' machen willst, dann fehlt mir aber definitiv noch eine Überprüfung, ob die Zahl im String überhaupt eine vernünftige Zahl ist, oder ob da nich wild und wahllos Buchstaben mit reingeworfen wurden. (Und sag nicht, dass das bei StrtoFloat schon integriert ist, da würde eine Welt für mich zusammenbrechen. ))

    Geändert von Moyaccercchi (13.11.2006 um 19:49 Uhr)

  3. #3
    Nicht euer ernst oder? Wenn schon, dann gleich richtig. Also als Parser implentiert, wie etwa hier: http://delphi.zsg-rottenburg.de/parser.html

    Vor allem das erste Beispiel könnte dir einfach aufschluss geben wie sowas gehen sollte.

    Code:
    function anfang(s:string;c:char):string;
    begin
      anfang:=copy(s,1,pos(c,s)-1);
    end;
    
    function copyab(const s:string; const i:integer):string;
      begin result:=copy(s,i,length(s)-i+1) end;
    
    function ende(s:string; c:char):string;
    begin
      ende:=copyab(s,pos(c,s)+1)
    end;
    
    function TermToReal(s:string):real;
    begin
      if pos('+',s)>0  then
        result:=TermToReal(anfang(s,'+'))+TermToReal(ende(s,'+')) 
      else if pos('*',s))>0 then
        result:=TermToReal(anfang(s,'*'))*TermToReal(ende(s,'*'))
      else
        result:=StrToFloat(s);
    end;
    Solte klar und gut verständlich sein.

  4. #4
    Hallo ich bin der totale blutige Anfänger und bin gerade dabei meinen ersten Taschenrechner zu proggn.
    So und ich sitze jetzt schon ein paar stunden nur an einer kleinen Sache xD
    Also es ist warscheinlich nur ne kleinigkeit darum findet man darüber auch einfach nichts.

    Code:
    result := StrToFloat (alt2) + 'rechenart' + StrToFloat (edit1.text);
    erklärung dazu,
    ich habe ebend die zahlen und einen = Button.
    Das Ergebnis soll erst ausgegeben werden wenn ich auf = drücke.
    Dazu habe ich "rechenart" als string und immer wenn ich zb auf + drücke rechenart = + oder -

    Der das Problem is in dem Code das ich nicht weis wie ich das in die Zeile einfügen soll?Also das "rechenart" ersetzt in der zeile jetzt praktisch einfach nur das + oder - je nachdem wo ich drauf klicke.

    Bitte helft mir xD

  5. #5
    Erstmal willkommen im Forum

    Zweitens: Das Programmieren eines Taschenrechners ist lang nicht so einfach, wie immer gedacht wird und ich bin der Meinung, dass es für einen Anfänger zu schwer ist, auch wenn man immer was anderes liest.
    Aber ein Taschenrechner funktioniert Zustandsorientiert (Punkt vor Strich Rechnung oder Klammersetzung) und da kommen dann die deterministischen Automaten ins Spiel.

    drittens: Dass, was du vor hast, kannst du mit einer Case-Anweisung realisieren.

    Code (delphi):
     
    case (rechenart) of 
      '+' : StrToFloat (alt2) + StrToFloat (edit1.text);
      '-' : StrToFloat (alt2) - StrToFloat (edit1.text);
      '*' : StrToFloat (alt2) * StrToFloat (edit1.text);
      '/' : StrToFloat (alt2) / StrToFloat (edit1.text);
    end;

  6. #6
    ah danke tolle begrüßung hier
    ich habe aber auch gelesen dass wenn man das grundprinziep hat (so wie ich fast) dann kann man sehr gut erweitern darum soll es ziehmlich gut als anfang sein.

    So jetzt habe ich aber noch eine Frage dazu,
    funktioniert das so einfach wie ich denke?
    Also ich gebe bei nem oneclick button einfach an rechenart := ('+'); und dann sucht der sich das im dem case selbst?

  7. #7
    mmh, so, wie ich das sehe, hast du ja was anderes vor, als ich dachte ^^"

    Du willst also zuerst die komplette Berechnung eingeben und erst dann die Berechnung ausführen.
    Dazu müsstest du dann wohl zwei dynamische Arrays (eins für die Zahlen und eins für die Rechenzeichen) (es gibt bessere Wege aber die sich für dich wohl zu kompliziert. Stichwort: verkettete Listen bzw. Stacks und Zeiger) nehmen und die Werte zwischenspeichern und beim Gleichheitszeichen-Button werden die Arrays mit einer Schleife durchgearbeitet.
    Dieses ist aber dann nicht mathematisch korrekt, weil die Punkt- vor Strichrechnung-Regel nicht eingehalten wird.

    Ich sag ja, es ist nicht so leicht, ein Taschenrechner zu basteln ^^

  8. #8
    bis jetzt ist es so dass man ja nur + und - rechnen kann.
    ich dachte eigentlich das ich zb beim + button rechenart := ('+'); und beim - dasselbe mit - machen kann und dann beim klick auf = die alte zahl und die neue zahl mit dem rechenart zeichen in der mitte zusammensetzen kann.das wäre zumindest für mich logisch und einfach.Nur da war ebend das problem das ich nicht weis wie ich das schreiben soll oben war ja die zeile wo ich nicht weitergekommen bin.
    Einfach Frage geht das überhaupt so?

  9. #9
    Ich denke, den Code den Whiz in #5 gepostet hat, kannst du so 1:1 verwenden – falls ich dich richtig verstehe. Ist aber noch etwas unklar. Wie ich's verstehe:

    Es gibt die Buttons "0"-"9", "+", "-" und "=". Erst gibt man eine Zahl ein, dann entweder "+" oder "-", dann noch eine Zahl und dann "=", woraufhin das Ergebnis erscheinen soll. (Falls man statt dem "=" auch nochmal Operator und Zahl eingeben können soll, macht das eigentlich auch keinen Unterschied, außer dass du beim "=" halt rechenart zurücksetzen musst, sodass du nachher weißt, dass du die neue Zahl direkt übernimmst.)

    Stimmt das so? Dann geht es tatsächlich einfach so. Wenn er eine der drei Nicht-Ziffern-Tasten drückt, führst du die Operation aus, speicherst das Ergebnis in result und setzt anschließen alt2 auf den Wert im Textfeld. Dann das Textfeld auf result, plus irgendeinen internen Switch damit du weißt, dass die nächste Zahlentaste das Feld wieder komplett löscht.

    Jedenfalls wäre, falls dir das noch nicht hilft (oder mein Gebrabbel ebenso verwirrend ist XD), eine detaillierte Skizzierung des Ablaufs bzw. des gewünschten Programm-Verhaltens hilfreich. Was drückst du, was steht daraufhin im Textfeld…

    Disclaimer: Habe Delphi nie programmiert. XD

  10. #10
    das hast du richtig verstanden und das was du noch gesagt hast da habe ich tatsächlich noch nicht ganz so gedacht.
    Ich glaube ich poste mal etwas mehr

    Button 1
    Code:
    begin
        try
          edit1.Text :=  (edit1.text + '1');
        except
      edit1.Text := ('Fehler');
     end;
    das ist ein +
    Code:
    begin
      try
        rechenart := ('+');
        alt := StrToFloat (edit1.Text);
        edit1.clear;
      except
      edit1.Text := ('Fehler');
    end;
    das ist das clear

    Code:
    begin
    edit1.Clear;
    edit1.Text := ('')
    end;
    und das das =

    Code:
    begin
      try
          alt2 := FloatToStr (alt);
          rechenart := hier müsste jetzt alt2 + rechenzeichen + edit1.text
          edit1.text := Floattostr (rechenart);
      except
      edit1.Text := ('Fehler');
    end;
    und die eine zeile das weis ich jetzt nicht das es die anzeige löscht wenn ich nach dem = wieder eine zahl eingebe ist ja erstmal zweitens oder
    wenigstens das das grundprinziep funktioniert.
    Mein Problem ist hier wirklich nur die Schreibweise darum habe ich alt auch wieder in ein string verwandelt um dann beide ergebnisse wieder in einen gleitkommewert zu umzuwandeln um damit zu rechnen -> dazu steht oben die schreibweise.

    Geändert von heXXer (20.04.2010 um 06:56 Uhr)

  11. #11
    mmh, ich halte das Programm irgendwie für nicht grad tauglich. ^^
    Dein Problem könnte man mit einer Unit-Globalen Variable lösen. (Ich weiß, Globale Variablen sind böse. ^^)

    Du schreibst oben, bei den deklarationen bei private
    Code:
    var 
      rechenzeichen:char;
    Dann steht diese Variable in jeder Funktion/Prozedur dieser Unit zur Verfügung.
    Nun kannst du bei den + und - Button die Variable rechenart füllen.
    Bei = Button machst du dann eine Case-Anweisung, wie ich oben beschrieben habe.

    Geändert von Whiz-zarD (20.04.2010 um 11:01 Uhr)

  12. #12
    Zitat Zitat von heXXer Beitrag anzeigen
    Code:
    begin
      try
          alt2 := FloatToStr (alt);
          rechenart := hier müsste jetzt alt2 + rechenzeichen + edit1.text
          edit1.text := Floattostr (rechenart);
      except
      edit1.Text := ('Fehler');
    end;
    Mein Problem ist hier wirklich nur die Schreibweise darum habe ich alt auch wieder in ein string verwandelt um dann beide ergebnisse wieder in einen gleitkommewert zu umzuwandeln um damit zu rechnen -> dazu steht oben die schreibweise.
    Also das verstehe ich noch nicht.
    Erstens: Ich nehme an, da gehört "result := ..." und dann "edit1.text := Floattostr (result);", oder?
    Zweitens: Warum wandelst du alt extra in einen Sting um, nur um es anschließend sofort wieder in ein Float umzuwandeln? o_O"
    Drittens: Wie gesagt, in die Zeile gehört einfach Whiz' Case-Anweisung.
    Also insgesamt wohl so:
    Code (Delphi):
    begin
      try
          case (rechenart) of 
            '+' : result := alt + StrToFloat (edit1.text);
            '-' : result := alt - StrToFloat (edit1.text);
          end;
          edit1.text := Floattostr (result);
      except
      edit1.Text := ('Fehler');
    end;

    Wie gesagt habe ich aber noch nie Delphi programmiert oder mich auch nur damit beschäftigt, also bezüglich Sichtbarkeit von Variablen musst du dich an andere halten. Aber eigentlich müssten alle verwendeten Variablen für alle die3se Funktionen sichtbar sein, außer result.

    Und wie gesagt, damit die Zahlen beim Eingeben einer neuen Zahl dann wieder verschwinden, würde ich irgendeine Boolean Variable verwenden, die du im "="-Handler auf true setzt und dann in den Handlern der Zifferntasten abfragst (und wieder auf [tt]false[tt] setzt).
    Genauso kannst du's dann auch mit jeweils einer Zeile bei "+" und "-" hinbekommen, dass auch da die Zahlen erstmal stehen bleiben und erst mit Drücken der nächsten Zifferntaste verschwinden.

  13. #13
    hey danke euch beiden.warum ich das so gemacht hab kann ich dir sagen weil ich es einfach nicht weis, darum probiere ich viel rum bis es geht das ist meine lernmethode.wenn ich zu hause bin werd ich das probieren.Mal noch eine Frage ist "char" nur für rechenzeichen oder sonderzeichen?

  14. #14
    ich habe jetzt rechenart : char festgelegt (übrigends alle als globale varialblen)

    und jetzt meckert er hier
    Code:
    begin
      try
          case (rechenart) of 
            '+' : result := alt + StrToFloat (edit1.text);
            '-' : result := alt - StrToFloat (edit1.text);
          end;
          edit1.text := Floattostr (result);
      except
      edit1.Text := ('Fehler');
    end;
    bei der zeile

    Code:
    '+' : result := alt + StrToFloat (edit1.text) ;
    rum dass es der string inkompatibel ist und extendet also zu lang?
    was fehlt mir noch

  15. #15
    char ist für ein beliebiges Zeichen, Buchstabe, Ziffer, Leer- oder Sonderzeichen gleichermaßen.

    Und was meckert er genau? "dass es der string inkompatibel ist und extendet also zu lang?" sagt mir nicht wirklich was.
    Bzw.: Als was hast du Result definiert, eh als Float?

  16. #16
    also result war als double definiert.JETZT habe ich allerdings ein anderes dummes Anfängerproblem (bitte lacht nicht) ich habe gestern nicht " Projekt speichern" gemacht sondern nur speichern, als ich es vorhin geöffnet hab war zwar der code und gebaute rechner da aber als ich es kompilieren wollte hat es immer eine neue Form genommen, darum hab ich einfach mal projekt speichern gemacht neu geöffnet und da war alles leer
    Naja der rückschlag hält mich nicht auf aber heute und morgen hab ich leider keine zeit dazu.

    Ich danke euch und melde mich noch mal wenn ichs geschafft hab

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
  •