Ergebnis 1 bis 8 von 8
  1. #1
    Mitglied
    Registriert seit
    Dec 2011
    Beiträge
    4

    Standard Problem mit selbst Programmiertem rechner in C++

    Hallo,

    erstmal will ich euch kurz ein paar informationen geben bevor ich zu meinem Problem komme:

    Ich bin noch blutiger anfaenger was Programmieren angeht, kann ein bisschen C, C++ und turbo pascal [aus Info in der schule -> delphi] schreiben.
    Vorgestern hatte ich eine Idee wie ich eine Funktion schreiben kann, bei der man in der Console einen Term eingibt [z.B 5+5+20] und der dann direkt berrechnet wird, so wie mit meinem schultaschenrechner.
    Das ganze ist in C++ geschrieben und die Idee dahinter ist:
    1. man speichert den Term als C-Style String in eine Array
    2. alle Ziffern die zsm stehen werden als fertige Integer Zahlen in deine Array gespeichert und alle Opperatoren werden als char in eine Array gespeichert

    ich habe ein paar bildschirm ausgaben gemacht und zu sehen ob auch alles klappt und siehe da es funktioniert

    Problem:

    der letzte schritt sollte eigentlich sein, dass zahl[0]opperator[0]zahl[1].. etc einfach ausgerechnet werden .. doch ich weis nicht wie ich das machen soll. Irgendwie musste man einfach die variablen nacheinander schreiben und dass soll dann als normales Statement behandelt werden. Funktioniert das? Wenn nein wie koennte ich das sonst machen?

    Ich wuerde mich sehr ueber eure Hilfe freuen und sag schonmal danke im vorraus
    Und entschuldigt bitte meine miserabele gros und klein Schreibung [und ja ich kann keine ae's, ue's, oe's und kein sz schreiben ]

    hier haeng ich noch schnell meinen quellcode fuer diese funktion an:

    Spoiler: 

    #include <cstdlib>
    #include <iostream>

    using namespace std;

    int function_scan_en()
    {
    cout << "Insert Function:" << endl;
    char char_fct[82];
    cout << endl;
    cin >> char_fct;
    cout << endl; //scan fct

    int char_size;
    char_size = strlen(char_fct); //scan size of fct

    int char_ascii[81];
    for(int char_n = 0; char_n < char_size; char_n++)
    {
    char_ascii[char_n] = static_cast<int>(char_fct[char_n]);

    cout << char_ascii[char_n] << endl;

    } //write ascii-value of chars

    int char_type[81];
    for(int char_n = 0; char_n < char_size; char_n++)
    {
    cout << endl;

    if (char_ascii[char_n] == 42||char_ascii[char_n] == 43||char_ascii[char_n] == 45||char_ascii[char_n] == 47)
    {
    char_type[char_n] = 0;
    cout << char_type[char_n];
    }

    else if (char_ascii[char_n] == 48||char_ascii[char_n] == 49||char_ascii[char_n] == 50||char_ascii[char_n] == 51||char_ascii[char_n] == 52||char_ascii[char_n] == 53||char_ascii[char_n] == 54||char_ascii[char_n] == 55||char_ascii[char_n] == 56||char_ascii[char_n] == 57)
    {
    char_type[char_n] = 1;
    cout << char_type[char_n];
    }

    else
    {
    cout << "worng char insert!";
    }

    } //write char_type-value

    int char_n_1 = 1;
    char char_parts[81][82];
    int char_parts_counter = 0;
    int char_parts_length_counter = 0;
    for(int char_n = 0; char_n < char_size; char_n++)
    {
    cout << endl;

    char_parts[char_parts_counter][char_parts_length_counter] = char_fct[char_n];
    if(char_type[char_n] == char_type [char_n_1])
    {
    char_parts_length_counter = char_parts_length_counter + 1;
    }

    else if(char_type[char_n] != char_type [char_n_1])
    {
    char_parts_length_counter = char_parts_length_counter +1;
    char_parts[char_parts_counter][char_parts_length_counter] = 0;
    char_parts_counter = char_parts_counter + 1;
    char_parts_length_counter =0;
    }

    else
    {
    cout << "unknown error -.-" << endl;
    }

    char_n_1 = char_n_1 +1;
    } //ecpic algorythem, seperates chars!

    int number_x[81];
    int number_count = 0;
    int char_count = 0;
    char char_opperator[42];
    for(int char_n = 0; char_n < char_size; char_n++)
    {
    if (char_parts[char_n][0] == 48||char_parts[char_n][0] == 49||char_parts[char_n][0] == 50||char_parts[char_n][0] == 51||char_parts[char_n][0] == 52||char_parts[char_n][0] == 53||char_parts[char_n][0] == 54||char_parts[char_n][0] == 55||char_parts[char_n][0] == 56||char_parts[char_n][0] == 57)
    {
    number_x[number_count] = atoi(char_parts[char_n]);
    number_count = number_count +1;
    }

    if (char_parts[char_n][0] == 42||char_parts[char_n][0] == 43||char_parts[char_n][0] == 45||char_parts[char_n][0] == 47)
    {
    char_opperator[char_count] = char_parts[char_n][0];
    char_count = char_count + 1;
    }
    } //saving numbers and opperators

    for(int char_n = 0; char_n < char_size; char_n++)
    {
    cout << char_parts[char_n] << endl;
    } //printing char_parts

    cout << endl;
    for(int char_n = 0; char_n < number_count; char_n++)
    {
    cout << number_x[char_n] << endl;
    } //printing integer numbers



    cout << endl;
    cout << endl << char_size << endl; //printing char_size
    cout << endl << char_fct << endl; //printing the fct

    }


    Mfg JVision

  2. #2
    Brain-Progger Avatar von Yoshi Party
    Registriert seit
    Apr 2006
    Beiträge
    3.493

    Lightbulb Re: Problem mit selbst Programmiertem rechner in C++

    Einen Taschenrechner zu programmieren ist viel schwieriger als man zunächst meint, darum rate ich dir mit deinen "blutigen" Anfänger-Erfahrungen im Moment noch eher davon ab.
    Falls du unbedingt weiter machen willst, solltest du dir lieber ein paar fertige Parser aus dem Internet suchen

    Zu deiner Frage:
    Man kann den string "3 + 4" nicht ausführen. Du müsstest die Operation ('+' in dem Fall) vordefinieren und bei Bedarf mit den beiden Parametern (3 und 4), die in deinem Array gespeichert sind aufrufen
    Diese Methode funktioniert nur bei sehr einfachen ausdrücken.

    mfg Yoshi

  3. #3
    Wahnsinnige Backware Avatar von stefbrot
    Registriert seit
    May 2006
    Ort
    An meinem PC
    Beiträge
    2.490

    Standard Re: Problem mit selbst Programmiertem rechner in C++

    Erstmal ein paar grundlegende Dinge zu deinem Code:
    - Wenn du C++ programmierst verwendest du anstatt char arrays besser std::string. Zur Eingabe verwendest du dann getline(cin, deinstring). Das hat den Vorteil dass du auch beliebig lange Terme die auch Leerzeichen enthalten können eingeben kannst. Die Begrenzung auf 80 Zeichen ist völlig unnötig. C style strings sind unhandlich und fehleranfällig. Statt strlen dann einfach deinstring.length().

    - Einen String in ein Integer Array zu kopieren ist unnötig. Du kannst alle Vergleiche usw. auch direkt mit den chars machen. Gleich noch eine Kürzungsmöglichkeit mit dazu:
    Code:
    //statt
    if (char_ascii[char_n] == 48||char_ascii[char_n] == 49||char_ascii[char_n] == 50||char_ascii[char_n] == 51||char_ascii[char_n] == 52||char_ascii[char_n] == 53||char_ascii[char_n] == 54||char_ascii[char_n] == 55||char_ascii[char_n] == 56||char_ascii[char_n] == 57)
    // das hier
    if (meinstring[char_n] >= '0' && meinstring[char_n] <= '9')
    Das erkennt genauso alle Ziffern.

    - Statt einem zweidimensionalen Array char char_parts[81][82]; kann man wieder std::string verwenden und einen passenden STL-Container. vector<string> char_parts; zum Beispiel.

    - Ziemlich am Ende hast du zwei mal folgende Schleife:
    Code:
    for(int char_n = 0; char_n < char_size; char_n++)
    Die Schleife läuft viel zu lange, weil du char_size in der Bedingung hast, du willst aber eher char_parts_count. Das ist ein schönes Beispiel dafür wie schnell man einen Fehler macht wenn man Arrays benutzt. Mit einem Iterator über einen STL-Container hätte soetwas nicht passieren können.

    Das sind jetzt wie gesagt ein paar allgemeine Tipps zum Umgang mit C++. Das solltest du auf jeden Fall berücksichtigen, wenn du weiter mit C++ programmierst. Das ist noch lange nicht alles was man an deinem Code aussetzen kann, aber das was mit das wichtigste erschien.

    Und nun zu deinem Ansatz für den Rechner:
    So einen Parser für Funktionsterme zu bauen ist gar nicht so einfach. Wenn man jetzt mal von komplexeren Eingaben mit Klammern usw absieht ist dein Ansatz soweit richtig, dass du die Zahlen und Operatoren trennen musst und die Zahlen in int umwandeln. Das sieht zwar etwas umständlich aus bei dir, aber es funktioniert ja. Um das Ergebnis zu berechnen kannst du nicht einfach das ganze als Statement behandeln. Du musst schon nochmal durch deine Arrays (bzw. vector / string) durchgehen und für jeden Operator die Operation berechnen. Wenn du auf die Punkt vor Strich Regel verzichten willst ist das eine einfache Schleife mit einem switch .. case für die operatoren.

    Wenn du einen vollständig korrekt rechnenden Rechner willst, also mit Punkt vor Strich und Klammern, dann wird das ganze schon etwas komplizierter. Du musst beim Parsen einen Baum erstellen. Der erste Schritt ist immer das Zerlegen in einzelne Tokens (Zahlen, Operatoren, Klammern), ähnlich dem was du gemacht hast, nur mit mehr Möglichkeiten. Wenn das ohne Fehler klappt wird der Baum aufgebaut. Da das jetzt vermutlich ertmal zu viel für dich ist will ich das jetzt nicht weiter ausführen. Wenn du mehr wissen willst kannst du ruhig nachfragen, oder auch gezielt suchen, aber man fängt ja immer klein an, also verbessere erstmal dein Programm dass es so funktioniert wie du das gedacht hattest und dann kannst du weitersehen.

  4. #4
    Mitglied Avatar von Jodocus_
    Registriert seit
    Aug 2010
    Ort
    Groß Wasserland
    Beiträge
    338

    Standard Re: Problem mit selbst Programmiertem rechner in C++

    >> darum rate ich dir mit deinen "blutigen" Anfänger-Erfahrungen im Moment noch eher davon ab.

    Ich nicht. http://www.stroustrup.com/Programming/6_writing.ppt erklärt einem "blutigen" Anfänger, wie man in C++ einen Parser schreibt.

  5. #5
    Mitglied

    (Threadstarter)


    Registriert seit
    Dec 2011
    Beiträge
    4

    Standard Re: Problem mit selbst Programmiertem rechner in C++

    mh schade
    aber eigentlich kann ich doch einfach fuer jeden opperator der als char gespeichert ist eine funktion starten die die vorherige und nachfolgende zahl z.B addiert.
    Das problem waere dann nur noch das zuerst die multiplikationen ausgefuerht werden.
    oder?

  6. #6
    #-e^(i*pi) Avatar von toredo
    Registriert seit
    Sep 2006
    Beiträge
    802

    Standard Re: Problem mit selbst Programmiertem rechner in C++

    Ich würde zuerst einmal den Input parsen und eine Baumstruktur erstellen. D.h.:
    1) String entgegennehmen
    2) Mithilfe der Operatordefinitionen eine Baumstruktur erstellen
    3) Baumstruktur auflösen

    Beim zweiten Schritt musst du den String parsen. Ist nicht sonderlich schwer, jedoch wenn mans zum ersten Mal macht kanns etwas mühsam sein.

    Die Baumstrukutr sollte in etwa so aussehen (gilt für "1 * 2 + 3 * 4 + 5"):


    So eine Baumstrktur kann man dann rekursiv sehr einfach auflösen.

    Alternativ könnte man auch einen sehr guten Rechner (inkl. Parser) sehr einfach mit Bison & Flex erstellen und den dann im C++ Programm einbinden Das wär aber gecheatet xD

    mfG

  7. #7
    Mitglied

    (Threadstarter)


    Registriert seit
    Dec 2011
    Beiträge
    4

    Standard Re: Problem mit selbst Programmiertem rechner in C++

    erstmal danke fuer die ganzen Tips

    ich probier am besten erstmal mein programm zu verbessern das es erstmal wenigstens einfach rechnungen machen kann und dann schau ich mir mal den c++ string an und les mir das zu parsern durch.

  8. #8
    Mitglied Avatar von Cepper
    Registriert seit
    Feb 2008
    Ort
    Heilbronn
    Beiträge
    59

    Arrow Re: Problem mit selbst Programmiertem rechner in C++

    Zitat Zitat von stefbrot Beitrag anzeigen
    ...Wenn das ohne Fehler klappt wird der Baum aufgebaut....
    Jopp, richtig. Deshalb eignen sich für solche Arten von Problemen rekursive Funktionen, da arbeitet man nicht mehr mit Schleifen. In dem Buch "Einstieg in C++: 4. Auflage (Galileo Computing)" ist ein solches Problem beschrieben und ausführlich gelößt.

  9.  
     
     

Berechtigungen

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