-
21. 01. 2012, 11:40 #1Mitglied
- Registriert seit
- Dec 2011
- Beiträge
- 4
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
-
21. 01. 2012, 12:33 #2
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
-
21. 01. 2012, 13:19 #3
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:
Das erkennt genauso alle Ziffern.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')
- 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: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.Code:for(int char_n = 0; char_n < char_size; char_n++)
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.
-
21. 01. 2012, 13:21 #4
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.
-
21. 01. 2012, 13:21 #5Mitglied
(Threadstarter)
- Registriert seit
- Dec 2011
- Beiträge
- 4
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?
-
21. 01. 2012, 13:24 #6
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
-
21. 01. 2012, 14:54 #7Mitglied
(Threadstarter)
- Registriert seit
- Dec 2011
- Beiträge
- 4
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.
-
22. 01. 2012, 11:59 #8
Re: Problem mit selbst Programmiertem rechner in C++
-


Zitieren

mehr lesen...







Resident Evil 6 erscheint in...
Heute, 15:21 in gulli:news