Wenn kein Operator vor (
-
Er hatte schon einmal hier im Forum geschrieben, es ging tatsächlich um die Berechnung von Termen, damals noch immer in der Form ((a+b)+c) usw. Also jede Operation mit seinen Operanden jeweils geklammert.
Da ich davon ausgehe das der Term immernoch als ein string vorliegt, ist es wirklich das einfachste einfach Zeichen für Zeichen durchzugehen und zu schauen ob auf eine Ziffer eine öffnende Klammer folgt und in dem Fall ein * einzufügen und dann normal den Term aufzulösen.
-
Fellhuhn schrieb:
Er hatte schon einmal hier im Forum geschrieben, es ging tatsächlich um die Berechnung von Termen, damals noch immer in der Form ((a+b)+c) usw. Also jede Operation mit seinen Operanden jeweils geklammert.
genau darum gehts
also ich mache das Programm weder mit Tokens noch mit einem Baum... ich wurschtel mich sozusagen bisl durchs Programm.
Die Rechnung funktioniert auch das die Klammern wenn welche vorhanden sind vor dem Term (((2+2))) = 4 geht auch inzwischen ( Das war ja das was ich als letztes hier ins Forum geschrieben hatte)
jetzt bin ich soweit das ich halt Zeichen für Zeichen durchgehen muss/will um dann zu schauen ob auf eine Zahl eine KLammer folgt. dann ein * einzufügen.
Mein größter Problem ist die if Abfrage .. ich hab gerade keine idee wie ich sie formulieren muss/soll... hmm
da wollte ich einfach einpaar ideen von euch
gruß
PS: cool Fellhuhn das du dich an mich erinnerst hoffentlich ein gutes Zeichen
-
Auf die schnelle in etwa so:
std::string term = "(3(3+4))"; for(unsigned int i = 0; i < term.size() - 1; i++) if (std::isdigit(term[i]) && // aus <cctype> term[i+1] == '(') { std::string temp = term.substr(0, i+1); temp += '*'; temp += term.substr(i+1); term = temp; }
-
Virokams schrieb:
also ich mache das Programm weder mit Tokens noch mit einem Baum... ich wurschtel mich sozusagen bisl durchs Programm.
Aha, na gut. Wenn du unbedingt mit den Strings rumfummeln willst
Aber als Vorschlag, wenn du mal fertig bist: Probier mal die Variante mit Termbaum aus. Wäre ne nette Erweiterung und man lernt die Grundlagen vom Compilerbau. Falls dich sowas interessiert.
-
Abstrakte Semantik Bäume wären da zB ein Stichwort. Oder die simpleren Abstraken Syntax Bäume.
Über so einen anstrengenden Frickelkram habe ich damals meine Diplomarbeit geschrieben... in Ada... war die Hölle.
-
Fellhuhn schrieb:
Abstrakte Semantik Bäume wären da zB ein Stichwort. Oder die simpleren Abstraken Syntax Bäume.
Über so einen anstrengenden Frickelkram habe ich damals meine Diplomarbeit geschrieben... in Ada... war die Hölle.
Also ich werde das Programm bestimm nochmal "anders" lösen sobald es fertig ist.
Ist halt jetzt so angefangen, abgesprochen und genehmigt es erstmal so zu machen um so strcpy und so andere Problematiken mal kennen zu lernen und die Abläufe mal im Kopf zu verstehen.so zurück zum Code... bisl umgebaut sehen meine ersten schritte jetzt so aus:
for(int i = 0; i <= term[strlen(term)-1]; i++) { if (int isdigit(term[i]) && term[i+1] == '(') { strncpy (copyleft, term[0], term[i]); strncpy (copyright, term[i+1], term[strlen(term)-1); copyleft = // weiß ich noch nicht genau XD soll aber dann halt das + an copyleft angefügt werden und dann wieder zusammenführung mit copyright im nächsten Schritt strncat(); return berechne(temp); } } //hmmmmmmmmmmmm
-
Also da du mit char-Arrays arbeitest hast du natürlich etwas mehr Arbeit als wenn du std::string nehmen würdest. Aber das ist deine eigene geschaffene Hölle, da sind wir alle wohl mal durch.
In etwa so:
for(int i = 0; i < strlen(term)-1; i++) // du willst bis zum vorletzten Element { if (std::isdigit(term[i]) && term[i+1] == '(') { // jetzt hast du das Problem das du term theoretisch um 1 byte vergrößern musst. // ich gehe mal davon aus das term vom Typ char* ist. char *temp = new char[strlen(term)+2]; // neuer platz strncpy (temp, term, i+1); // alle zeichen bis zum neuen * kopieren temp[i+1] = '*'; // * einfügen strncpy (temp+i+2, term + i + 1, strlen(term)-i+1); delete[] term; // term wieder freigeben term = temp; // term zeigt jetzt auf den neu angeforderten speicher } }
-
Fellhuhn schrieb:
Also da du mit char-Arrays arbeitest hast du natürlich etwas mehr Arbeit als wenn du std::string nehmen würdest. Aber das ist deine eigene geschaffene Hölle, da sind wir alle wohl mal durch.
In etwa so:
for(int i = 0; i < strlen(term)-1; i++) // du willst bis zum vorletzten Element { if (std::isdigit(term[i]) && term[i+1] == '(') { // jetzt hast du das Problem das du term theoretisch um 1 byte vergrößern musst. // ich gehe mal davon aus das term vom Typ char* ist. char *temp = new char[strlen(term)+2]; // neuer platz strncpy (temp, term, i+1); // alle zeichen bis zum neuen * kopieren temp[i+1] = '*'; // * einfügen strncpy (temp+i+2, term + i + 1, strlen(term)-i+1); delete[] term; // term wieder freigeben term = temp; // term zeigt jetzt auf den neu angeforderten speicher } }
hehe ja richtig aber Hölle ist immer gut wie gesagt ich soll es erstmal so machen.
term ist const char * term ...
ansonsten Danke erstmal ich gucke gleich mal durch mache jetzt erstmal mittagspause
gruß
-
hab das jetzt mal so eingefügt... ausser das ich std:: vor dem isdigit wegmachen musste liefs dann... ABER ZACK sobald ich 2(2+2) zum Testen eingebe kommt error.
und zwar das angeblich irgendiwe der Hipe probleme kriegt oder so.
kann jetzt keinen Screen machen.aber es ist keine Fehlermeldung in der Fehlerliste sondern so ein Windoof Kritikal Error oder so... total wirsch...
ne ahnung?
-
Virokams schrieb:
hab das jetzt mal so eingefügt... ausser das ich std:: vor dem isdigit wegmachen musste liefs dann... ABER ZACK sobald ich 2(2+2) zum Testen eingebe kommt error.
und zwar das angeblich irgendiwe der Hipe probleme kriegt oder so.
kann jetzt keinen Screen machen.aber es ist keine Fehlermeldung in der Fehlerliste sondern so ein Windoof Kritikal Error oder so... total wirsch...
ne ahnung?
Alles was hier wirsch ist, ist deine Fehlerbeschreibung.
Was soll der Hipe sein? Was ist Windoof? Und was soll ein Kritikal Error sein?
-
Ahnung? Ja: char-Arrays.
Da wird wohl irgendwas mit der Allokierung und/oder Freigabe im Argen liegen.
-
Debug assertion failed!
Programm:...
dbgdel.ccp
Libe:52Expression: _BLOCK_TYPE_IS_VALID(pHead->nBlockUse)
so ich drücke retry
Das Programm hat einen Haltepunkt ausgelöst
ich kann damit garnichts anfangen.
Hipe ist doch der "kleine" Speicher wo Stacks oder locale Variablen gesp. werden
Windoof = Windowssry...
-
nochwas:
wenn ich schritt für schritt durchgehe
sobald ich diese Befehlszeile verlasse:
delete[] term; // term wieder freigeben
kommt der Fehler
also bei:
term = temp; // term zeigt jetzt auf den neu angeforderten speicher
SO die Lösung des Problems ist also:
Auskommentieren von: //delete[] term; // term wieder freigeben
for(int i = 0; i < strlen(term)-1; i++) // du willst bis zum vorletzten Element { if (isdigit(term[i]) && term[i+1] == '(') { // jetzt hast du das Problem das du term theoretisch um 1 byte vergrößern musst. // ich gehe mal davon aus das term vom Typ char* ist. char * temp = new char[strlen(term)+2]; // neuer platz strncpy (temp, term, i+1); // alle zeichen bis zum neuen * kopieren temp[i+1] = '*'; // * einfügen strncpy (temp+i+2, term + i + 1, strlen(term)-i+1); //delete[] term; // term wieder freigeben term = temp; // term zeigt jetzt auf den neu angeforderten speicher } }
Danke
Nur eins noch:
char * temp = new char[strlen(term)+2]; // neuer platz
was macht das ... versteh ich nicht
kann mir bestimmt jemand erläutern...
Danke Danke Danke
-
char * temp = new char[strlen(term)+2]; // neuer platz
Dynamische Anforderung von der Länge von term + 2 und temp auf den Anfang des C-Stringes zeigen lassen.
-
Hm, zeig mal die Initialisierung von term.
Mit new wird neuer Speicher angefordert und mit delete wird er wieder gelöscht. Läßt du das delete weg hast du ein klassisches Speicherleck.
-
Fellhuhn schrieb:
Hm, zeig mal die Initialisierung von term.
Mit new wird neuer Speicher angefordert und mit delete wird er wieder gelöscht. Läßt du das delete weg hast du ein klassisches Speicherleck.
int main()
{
char term[1024];double berechne (const char * term)
{}???
Ich habe dir mal peer Mail den kompletten Code geschickt... vielleicht ist es dann ersichtlicher WIE ich vorgehe... und vielleicht siehste dann besser den Fehler (obwohl es funktioniert )
-
for(int i = 0; i < strlen(term)-1; i++) // du willst bis zum vorletzten Element { if (std::isdigit(term[i]) && term[i+1] == '(') { // jetzt hast du das Problem das du term theoretisch um 1 byte vergrößern musst. // ich gehe mal davon aus das term vom Typ char* ist. char *temp = new char[strlen(term)+2]; // neuer platz strncpy (temp, term, i+1); // alle zeichen bis zum neuen * kopieren temp[i+1] = '*'; // * einfügen strncpy (temp+i+2, term + i + 1, strlen(term)-i+1); delete[] term; // term wieder freigeben term = temp; // term zeigt jetzt auf den neu angeforderten speicher } }
Entschuldigt bitte das ich mich hier mal mit reinhänge, aber irgendwie verstehe ich die oberen Zeilen nicht so ganz. Sollte dort vor verlassen der
for
-Schleife nicht auch wiedertemp
freigegeben werden? Oder habe ich vielleicht gerade ein Brett vorm Kopf?
-
Virokams schrieb:
Debug assertion failed!
Programm:...
dbgdel.ccp
Libe:52Expression: _BLOCK_TYPE_IS_VALID(pHead->nBlockUse)
Daran wirst du dich gewöhnen müssen, wenn du es mit
char*
und deinem Gefrickel durchziehen willst. Du solltest einfach wissen, dass es einfacher geht.Mizar schrieb:
Sollte dort vor verlassen der
for
-Schleife nicht auch wiedertemp
freigegeben werden? Oder habe ich vielleicht gerade ein Brett vorm Kopf?Nein, der von der alten Variable
term
referenzierte Speicherbereich wird ja in den neu angelegten Bereich (vom Zeigertemp
) kopiert. Anschliessend wird der alte Speicher vonterm
freigegeben. Zuletzt zeigtterm
auf den neuen Inhalt (vontemp
).
-
Nexus schrieb:
Mizar schrieb:
Sollte dort vor verlassen der
for
-Schleife nicht auch wiedertemp
freigegeben werden? Oder habe ich vielleicht gerade ein Brett vorm Kopf?Nein, der von der alten Variable
term
referenzierte Speicherbereich wird ja in den neu angelegten Bereich (vom Zeigertemp
) kopiert. Anschliessend wird der alte Speicher vonterm
freigegeben. Zuletzt zeigtterm
auf den neuen Inhalt (vontemp
).Ok, das habe ich jetzt verstanden :). Herrje, ich muss mich mal mehr mit
new
unddelete
und auch noch mehr mit Zeigern auseinandersetzen.
-
Nexus schrieb:
Virokams schrieb:
Debug assertion failed!
Programm:...
dbgdel.ccp
Libe:52Expression: _BLOCK_TYPE_IS_VALID(pHead->nBlockUse)
Daran wirst du dich gewöhnen müssen, wenn du es mit
char*
und deinem Gefrickel durchziehen willst. Du solltest einfach wissen, dass es einfacher geht.Ich weiß das es einfacher geht. es ist ja sozusagen mein erstes Programm... meine ersten schritte und ich soll es so machen (Anweisung von oben) um zu üben ...
beim nächstenmal geh ich bestimmt mal anders an die Sache
Aber danke für die Hilfe zu diesem Thema super Forum
Danke FellhuhnGruß