|
You last visited: Today at 18:32
Advertisement
C++ - "Terme-Parser" in C - "Terme-Parser" umwandeln
Discussion on C++ - "Terme-Parser" in C - "Terme-Parser" umwandeln within the C/C++ forum part of the Coders Den category.
12/11/2010, 10:22
|
#1
|
elite*gold: 77
Join Date: May 2008
Posts: 5,430
Received Thanks: 5,878
|
C++ - "Terme-Parser" in C - "Terme-Parser" umwandeln
Ich hab mir einen Parser gebastelt, der mir einfach Terme löst und das Ergebniss zurückgibt. Das ganze habe ich mit C / C++ gemacht, ich bin aber gezwungen das ganze in reinen C - Code umzuwandeln.
Ich habe mich auch schon versucht, aber da ich wirklich extrem wenig und ungern Elemente aus C verwende bin ich gescheitert.
Hier mein C/C++ Code:
PHP Code:
#include <iostream> #include <string.h> #include <stdio.h> #include <sstream> #include <math.h>
using namespace std;
double Calculate(string str) { int size=str.length(); string calcs[str.length()*2]; bool operat=0; int number=0; while (1) { cout<<str<<"\n"; ////// Resetten der Variablen Start ////// number=0; operat=0; ////// Resetten der Variablen Ende //////
for (int i=0; i<str.length(); i++) // Die Schleife durchläuft den kompletten Eingabe-String { if ((str[i]>47 && str[i]<58) || str[i]==46) // Wenn ein Zeichen zwischen AscII-Code 48 (=0) und 57 (=9) oder wenn ein Punkt (. für Komma) gefunden wurde // Dann gehört das zu einer Zahl und bekommt einen extra Platz in calcs[] { calcs[number]+=str[i]; // Die Zahl bekommt einen Platz in dem Array calcs[] operat=0; // Die Zahl ist kein Operator (+-*/^) , also setzen wir operat zu 0 } else if ( (str[i]>39 && str[i]<44) || str[i]==94 || str[i]==47 ||str[i]==45 ) // Wenn einer der Operatoren ()*+^/- gefunden wurde, dann ist die Bedingung wahr { if ((operat==1 || i==0) && (str[i]==45 || str[i]==43) ) // Wenn wir schoneinmal einen Operator gefunden haben oder wenn wir das // erste Zeichen in dem String überprüfen und wir einen Plus oder Minus Operator finden // dann muss der + bzw. - Operator zu einer Zahl gehören, z.b. // -12+-2 // bzw. 12--3 { calcs[number]+=str[i]; // Unser Zeichen bekommt also den selben Platz wie unsere Zahl } else // Ansonsten wenn der Operator nicht zu einer Zahl gehört { number++; // Unser Operator bekommt den nächsten Platz in calcs calcs[number]+=str[i]; number++; // Der Operator steht alleine in calcs[number], es wird also gleich ein Schritt weitergezählt operat=1; // Wir haben einen Operator gefunden
}
} }
str="";
for (int i=0; i<number; i++) // Eine Schleife, die durch alle unsere Operatoren/Zahlen läuft { if ((calcs[i][0]>47 && calcs[i][0]<58)||(calcs[i][1]>47 && calcs[i][1]<58)) // Wenn wir an diesem Platz des Arrays calcs eine Zahl haben, dann ist die Bedingung wahr // Wir überprüfen ob wir eine Zahl haben, indem wir uns nur das erste Zeichen anschauen // wenn das erste Zeichen eine Zahl ist, dann ist alles eine Zahl // Falls das erste Zeichen keine Zahl ist, kann es immernoch sein, dass wir es mit // einer vorzeichenbehafteten Zahl zu tun haben (z.b. -44) // Also müssen wir auch noch das 2. Zeichen überprüfen {
if (calcs[i+1]=="^" && calcs[i+2]!="" && ((calcs[i+2][0]>47 && calcs[i+2][0]<58)||(calcs[i+2][1]>47 && calcs[i+2][1]<58))) // calcs[i] muss eine Zahl sein und calcs[i+2] muss eine Zahl sein // Damit wir wissen was wir mit den beiden Zahlen machen müssen, // schauen wir uns an was calcs[i+1] ist. // Ist calcs[i+1] also ^ und calcs[i] eine Zahl und calcs[i+2] auch eine Zahl, // Dann können wir ruhig den Code ausführen lassen
// Wir lassen ^ zuerst überprüfen, da ^ die höchste Priorität hat. // danach kommt */ und dann +- { calcs[i]=NumberToString(pow(StringToNumber(calcs[i]),StringToNumber(calcs[i+2]))); calcs[i+2]=""; // Reset der Zahl, da wir sie schoneinmal verrechnet haben calcs[i+1]=""; // Reset der Zahl, da wir sie schoneinmal verrechnet haben break; // Wir dürfen immer nur eine Operation pro Durchgang machen (eventuel sind nach dieser // einen Operation Klammern verschwunden und wir müssen das was zwischen den Klammern // steht immer zuerst ausrechnen } else if (calcs[i+1]=="*" && calcs[i+2]!="" && ((calcs[i+2][0]>47 && calcs[i+2][0]<58)||(calcs[i+2][1]>47 && calcs[i+2][1]<58)) && calcs[i+3]!="^") // Wenn wir also kein ^ gefunden haben, sondern ein * { calcs[i]=NumberToString(StringToNumber(calcs[i])*StringToNumber(calcs[i+2])); calcs[i+2]=""; calcs[i+1]=""; break; } else if (calcs[i+1]=="/" && calcs[i+2]!="" && ((calcs[i+2][0]>47 && calcs[i+2][0]<58)||(calcs[i+2][1]>47 && calcs[i+2][1]<58)) && calcs[i+3]!="^") // Dasselbe wie oben nur mit / { calcs[i]=NumberToString(StringToNumber(calcs[i])/StringToNumber(calcs[i+2])); calcs[i+2]=""; calcs[i+1]=""; break; } else if (calcs[i+1]=="+" && calcs[i+2]!="" && ((calcs[i+2][0]>47 && calcs[i+2][0]<58)||(calcs[i+2][1]>47 && calcs[i+2][1]<58)) && calcs[i+3]!="*" && calcs[i+3]!="/" && calcs[i+3]!="^") // Dasselbe wie oben nur mit + { calcs[i]=NumberToString(StringToNumber(calcs[i])+StringToNumber(calcs[i+2])); calcs[i+2]=""; calcs[i+1]=""; break; } else if (calcs[i+1]=="-" && calcs[i+2]!="" && ((calcs[i+2][0]>47 && calcs[i+2][0]<58)||(calcs[i+2][1]>47 && calcs[i+2][1]<58)) && calcs[i+3]!="*" && calcs[i+3]!="/" && calcs[i+3]!="^") // Dasselbe wie oben nur mit - {
calcs[i]=NumberToString(StringToNumber(calcs[i])-StringToNumber(calcs[i+2])); calcs[i+2]=""; calcs[i+1]=""; break; }
} else if(calcs[i]=="(") // Wir haben also an der Stelle calcs[i] keine Zahl, sondern eine geöffnete Klammer { if (((calcs[i+1][0]>47 && calcs[i+1][0]<58) || (calcs[i+1][1]>47 && calcs[i+1][1]<58)) && calcs[i+2]==")") // Wenn calcs[i+1] eine Zahl ist, dann sollten wir einmal überprüfen ob calcs[i+2] eine geschlossene Klammer ist // und ob zwischen der geöffneten Klammer (calcs[i]) und der Geschlossenen (calcs[i+2]) eine zahl ist, // Wenn dort nur eine Zahl ist, dann können wir die Klammern entfernen { calcs[i+2]=""; // Klammern werden entfernt calcs[i]=""; // Klammern werden entfernt break; // Wie immer darf alles nur einmal durchlaufen werden } }
} for (int i=0; i<=number; i++) { str+=calcs[i]; // Es wird ein neuer Term gebildet, aus den vorhandenen calcs[i]=""; // Resetten des Inhalts } if (number<=2) break; // Wenn wir 2 oder weniger Nummern gefunden haben, dann wird unsere Schleife verlassen // Bei 2 Nummern reicht ein Durchgang und deswegen kann danach verlassen werden }
return StringToNumber(str); // returnt das Ergebniss
}
double StringToNumber(string str) { stringstream Str; Str << str; double d; Str >> d; return d; }
string NumberToString(double d) { ostringstream Str; Str << d; string ZahlAlsString(Str.str()); return ZahlAlsString; }
Und hier der Versuch von mir in C-Code (Von der alten Version):
PHP Code:
#include <iostream> #include <stdio.h> #include <math.h> #include <stdlib.h>
double Calculate(char* str) { unsigned char count=0; char calcs[10][11]; bool operat=0; unsigned char number=0; for (short i=0;i<sizeof(str);i++) { if ((str[i]>47 && str[i]<58) || str[i]==46) { calcs[number][count]=str[i]; count++; } else if ( (str[i]>39 && str[i]<44) || str[i]==94 || str[i]==47 ||str[i]==45 ) { if ((operat==1 || i==0) && (str[i]==45 || str[i]==43) ) { calcs[number][count]=str[i]; count++; } else { number++; count=0; calcs[number][count]=str[i]; number++; count=0; operat=1;
}
} } str="";
for (unsigned char i=0;i<number;i++) { if ((calcs[i][0]>47 && calcs[i][0]<58)||(calcs[i][1]>47 && calcs[i][1]<58)) {
if (calcs[i+1][0]=='^' && calcs[i+1][1]==NULL && calcs[i+2][0]!=NULL && ((calcs[i+2][0]>47 && calcs[i+2][0]<58)||(calcs[i+2][1]>47 && calcs[i+2][1]<58))) { NumberToString(pow(StringToNumber(calcs[i]),StringToNumber(calcs[i+2])),calcs[i]); //calcs[i+2]=""; for (char ii=0;ii<10;ii++) { calcs[i+1][ii]='"'; calcs[i+2][ii]='"'; }
break; } else if (calcs[i+1][0]=='*' && calcs[i+1][1]==NULL && calcs[i+2][0]!=NULL && ((calcs[i+2][0]>47 && calcs[i+2][0]<58)||(calcs[i+2][1]>47 && calcs[i+2][1]<58)) && calcs[i+3]!="^") { NumberToString(StringToNumber(calcs[i])*StringToNumber(calcs[i+2]),calcs[i]); for (char ii=0;ii<10;ii++) { calcs[i+1][ii]='"'; calcs[i+2][ii]='"'; } break; } else if (calcs[i+1][0]=='/' && calcs[i+1][1]==NULL && calcs[i+2][0]!=NULL && ((calcs[i+2][0]>47 && calcs[i+2][0]<58)||(calcs[i+2][1]>47 && calcs[i+2][1]<58)) && calcs[i+3]!="^") { NumberToString(StringToNumber(calcs[i])/StringToNumber(calcs[i+2]),calcs[i]); for (char ii=0;ii<10;ii++) { calcs[i+1][ii]='"'; calcs[i+2][ii]='"'; } break; } else if (calcs[i+1][0]=='+' && calcs[i+1][1]==NULL && calcs[i+2][0]!=NULL && ((calcs[i+2][0]>47 && calcs[i+2][0]<58)||(calcs[i+2][1]>47 && calcs[i+2][1]<58)) && calcs[i+3]!="*" && calcs[i+3]!="/" && calcs[i+3]!="^") { NumberToString(StringToNumber(calcs[i])+StringToNumber(calcs[i+2]),calcs[i]); for (char ii=0;ii<10;ii++) { calcs[i+1][ii]='"'; calcs[i+2][ii]='"'; } break; } else if (calcs[i+1][0]=='-' && calcs[i+1][1]==NULL && calcs[i+2][0]!=NULL && ((calcs[i+2][0]>47 && calcs[i+2][0]<58)||(calcs[i+2][1]>47 && calcs[i+2][1]<58)) && calcs[i+3]!="*" && calcs[i+3]!="/" && calcs[i+3]!="^") {
NumberToString(StringToNumber(calcs[i])-StringToNumber(calcs[i+2]),calcs[i]); //cout<<calcs[i]; for (char ii=0;ii<10;ii++) { calcs[i+1][ii]='"'; calcs[i+2][ii]='"'; } break; }
} else if(calcs[i][0]=='(') { if (((calcs[i+1][0]>47 && calcs[i+1][0]<58) || (calcs[i+1][1]>47 && calcs[i+1][1]<58)) && calcs[i+2]==")") { for (char ii=0;ii<10;ii++) { calcs[i][ii]='"'; calcs[i+2][ii]='"'; } break; } else if ((((calcs[i+1][0]=='+' && calcs[i+1][1]==NULL) || (calcs[i+1][0]=='-' && calcs[i+1][1]==NULL)) && calcs[i+1][1]>47 && calcs[i+1][1]<58) || (calcs[i+1][0]>47 && calcs[i+1][0]<58) && calcs[i+2][0]==')') { for (char ii=0;ii<10;ii++) { calcs[i][ii]='"'; calcs[i+2][ii]='"'; } break; } }
} cout<<sizeof(str)<<"\n";
unsigned char ai=0; for (unsigned char i=0;i<=number;i++) { for (unsigned char ii=0;ii<10;ii++) { cout<<calcs[i][ii]<<" "; if (calcs[i][ii]!='"') { //cout<<"!"<<str[ai]; //str[ai]=calcs[i][ii]; //cout<<"!"; ai++; } else break; } } cout<<2; cout<<str; if (number>2) Calculate(str); return StringToNumber(str);
}
double StringToNumber(char* str) { return atof(str); }
void NumberToString(double i,char* buffer) { sprintf(buffer, "%f", i); }
Edit:
Ich habe den Code jetzt auskommentiert und hier nocheinmal ein "Anwendungsbeispiel":
PHP Code:
#include <iostream> #include <string.h> #include <stdio.h> #include <sstream> #include <math.h>
using namespace std;
double Calculate(string str); double StringToNumber(string str); string NumberToString(double d); int main() { cout<<Calculate("(2*3)+4*2+(2*10+8)*(2-2)-2+5"); }
double Calculate(string str) { int size=str.length(); string calcs[str.length()*2]; bool operat=0; int number=0; while (1) { cout<<str<<"\n"; ////// Resetten der Variablen Start ////// number=0; operat=0; ////// Resetten der Variablen Ende //////
for (int i=0; i<str.length(); i++) // Die Schleife durchläuft den kompletten Eingabe-String { if ((str[i]>47 && str[i]<58) || str[i]==46) // Wenn ein Zeichen zwischen AscII-Code 48 (=0) und 57 (=9) oder wenn ein Punkt (. für Komma) gefunden wurde // Dann gehört das zu einer Zahl und bekommt einen extra Platz in calcs[] { calcs[number]+=str[i]; // Die Zahl bekommt einen Platz in dem Array calcs[] operat=0; // Die Zahl ist kein Operator (+-*/^) , also setzen wir operat zu 0 } else if ( (str[i]>39 && str[i]<44) || str[i]==94 || str[i]==47 ||str[i]==45 ) // Wenn einer der Operatoren ()*+^/- gefunden wurde, dann ist die Bedingung wahr { if ((operat==1 || i==0) && (str[i]==45 || str[i]==43) ) // Wenn wir schoneinmal einen Operator gefunden haben oder wenn wir das // erste Zeichen in dem String überprüfen und wir einen Plus oder Minus Operator finden // dann muss der + bzw. - Operator zu einer Zahl gehören, z.b. // -12+-2 // bzw. 12--3 { calcs[number]+=str[i]; // Unser Zeichen bekommt also den selben Platz wie unsere Zahl } else // Ansonsten wenn der Operator nicht zu einer Zahl gehört { number++; // Unser Operator bekommt den nächsten Platz in calcs calcs[number]+=str[i]; number++; // Der Operator steht alleine in calcs[number], es wird also gleich ein Schritt weitergezählt operat=1; // Wir haben einen Operator gefunden
}
} }
str="";
for (int i=0; i<number; i++) // Eine Schleife, die durch alle unsere Operatoren/Zahlen läuft { if ((calcs[i][0]>47 && calcs[i][0]<58)||(calcs[i][1]>47 && calcs[i][1]<58)) // Wenn wir an diesem Platz des Arrays calcs eine Zahl haben, dann ist die Bedingung wahr // Wir überprüfen ob wir eine Zahl haben, indem wir uns nur das erste Zeichen anschauen // wenn das erste Zeichen eine Zahl ist, dann ist alles eine Zahl // Falls das erste Zeichen keine Zahl ist, kann es immernoch sein, dass wir es mit // einer vorzeichenbehafteten Zahl zu tun haben (z.b. -44) // Also müssen wir auch noch das 2. Zeichen überprüfen {
if (calcs[i+1]=="^" && calcs[i+2]!="" && ((calcs[i+2][0]>47 && calcs[i+2][0]<58)||(calcs[i+2][1]>47 && calcs[i+2][1]<58))) // calcs[i] muss eine Zahl sein und calcs[i+2] muss eine Zahl sein // Damit wir wissen was wir mit den beiden Zahlen machen müssen, // schauen wir uns an was calcs[i+1] ist. // Ist calcs[i+1] also ^ und calcs[i] eine Zahl und calcs[i+2] auch eine Zahl, // Dann können wir ruhig den Code ausführen lassen
// Wir lassen ^ zuerst überprüfen, da ^ die höchste Priorität hat. // danach kommt */ und dann +- { calcs[i]=NumberToString(pow(StringToNumber(calcs[i]),StringToNumber(calcs[i+2]))); calcs[i+2]=""; // Reset der Zahl, da wir sie schoneinmal verrechnet haben calcs[i+1]=""; // Reset der Zahl, da wir sie schoneinmal verrechnet haben break; // Wir dürfen immer nur eine Operation pro Durchgang machen (eventuel sind nach dieser // einen Operation Klammern verschwunden und wir müssen das was zwischen den Klammern // steht immer zuerst ausrechnen } else if (calcs[i+1]=="*" && calcs[i+2]!="" && ((calcs[i+2][0]>47 && calcs[i+2][0]<58)||(calcs[i+2][1]>47 && calcs[i+2][1]<58)) && calcs[i+3]!="^") // Wenn wir also kein ^ gefunden haben, sondern ein * { calcs[i]=NumberToString(StringToNumber(calcs[i])*StringToNumber(calcs[i+2])); calcs[i+2]=""; calcs[i+1]=""; break; } else if (calcs[i+1]=="/" && calcs[i+2]!="" && ((calcs[i+2][0]>47 && calcs[i+2][0]<58)||(calcs[i+2][1]>47 && calcs[i+2][1]<58)) && calcs[i+3]!="^") // Dasselbe wie oben nur mit / { calcs[i]=NumberToString(StringToNumber(calcs[i])/StringToNumber(calcs[i+2])); calcs[i+2]=""; calcs[i+1]=""; break; } else if (calcs[i+1]=="+" && calcs[i+2]!="" && ((calcs[i+2][0]>47 && calcs[i+2][0]<58)||(calcs[i+2][1]>47 && calcs[i+2][1]<58)) && calcs[i+3]!="*" && calcs[i+3]!="/" && calcs[i+3]!="^") // Dasselbe wie oben nur mit + { calcs[i]=NumberToString(StringToNumber(calcs[i])+StringToNumber(calcs[i+2])); calcs[i+2]=""; calcs[i+1]=""; break; } else if (calcs[i+1]=="-" && calcs[i+2]!="" && ((calcs[i+2][0]>47 && calcs[i+2][0]<58)||(calcs[i+2][1]>47 && calcs[i+2][1]<58)) && calcs[i+3]!="*" && calcs[i+3]!="/" && calcs[i+3]!="^") // Dasselbe wie oben nur mit - {
calcs[i]=NumberToString(StringToNumber(calcs[i])-StringToNumber(calcs[i+2])); calcs[i+2]=""; calcs[i+1]=""; break; }
} else if(calcs[i]=="(") // Wir haben also an der Stelle calcs[i] keine Zahl, sondern eine geöffnete Klammer { if (((calcs[i+1][0]>47 && calcs[i+1][0]<58) || (calcs[i+1][1]>47 && calcs[i+1][1]<58)) && calcs[i+2]==")") // Wenn calcs[i+1] eine Zahl ist, dann sollten wir einmal überprüfen ob calcs[i+2] eine geschlossene Klammer ist // und ob zwischen der geöffneten Klammer (calcs[i]) und der Geschlossenen (calcs[i+2]) eine zahl ist, // Wenn dort nur eine Zahl ist, dann können wir die Klammern entfernen { calcs[i+2]=""; // Klammern werden entfernt calcs[i]=""; // Klammern werden entfernt break; // Wie immer darf alles nur einmal durchlaufen werden } }
} for (int i=0; i<=number; i++) { str+=calcs[i]; // Es wird ein neuer Term gebildet, aus den vorhandenen calcs[i]=""; // Resetten des Inhalts } if (number<=2) break; // Wenn wir 2 oder weniger Nummern gefunden haben, dann wird unsere Schleife verlassen // Bei 2 Nummern reicht ein Durchgang und deswegen kann danach verlassen werden }
return StringToNumber(str); // returnt das Ergebniss
}
double StringToNumber(string str) { stringstream Str; Str << str; double d; Str >> d; return d; }
string NumberToString(double d) { ostringstream Str; Str << d; string ZahlAlsString(Str.str()); return ZahlAlsString; }
Falls jemand einen kostenlosen Opensource-C-Parser hat, dann kann er ihn mir auch schicken.
|
|
|
12/11/2010, 14:59
|
#2
|
elite*gold: 20
Join Date: Sep 2006
Posts: 1,100
Received Thanks: 184
|
Code:
for (short i=0;i<sizeof(str);i++)
Diese Codezeile macht mich sehr sehr traurig, sizeof kann nur größen ermitteln die zur Zeit des Kompilierens bekannt sind, außerdem ist die Größe des Chararrays überhaupt nicht was du wissen willst, dich interessiert doch die String länge, also benützt auch die strlen Funktion.
Desweiteren kannst du in C keine Variablen im schleifenkopf deklarieren.
Ansonsten habe ich jetzt den Code noch nicht weiter inspiziert, denn die C Version hast du überhaupt nicht kommentiert, was mir allerdings aufgefallen ist, das while(1) aus der C++ Version fehlt in der C Version.
Codepad.org kann übrigens auch C kompilieren.
|
|
|
12/11/2010, 15:12
|
#3
|
elite*gold: 77
Join Date: May 2008
Posts: 5,430
Received Thanks: 5,878
|
Quote:
Originally Posted by Bot_interesierter
Code:
for (short i=0;i<sizeof(str);i++)
Diese Codezeile macht mich sehr sehr traurig, sizeof kann nur größen ermitteln die zur Zeit des Kompilierens bekannt sind, außerdem ist die Größe des Chararrays überhaupt nicht was du wissen willst, dich interessiert doch die String länge, also benützt auch die strlen Funktion.
Desweiteren kannst du in C keine Variablen im schleifenkopf deklarieren.
Ansonsten habe ich jetzt den Code noch nicht weiter inspiziert, denn die C Version hast du überhaupt nicht kommentiert, was mir allerdings aufgefallen ist, das while(1) aus der C++ Version fehlt in der C Version.
Codepad.org kann übrigens auch C kompilieren.
|
Endlich versteh ich warum das nicht funktionieren kann. 
Die for-Schleife hat mir nicht direkt einen fehler geliefert...
Aber ok, ich werde das aucheinmal beachten und dann den Code posten.
Danke aufjedenfall schoneinmal.
Edit:
Danke, endlich funktioniert es, falls es jemanden intressiert:
PHP Code:
#include <stdio.h> #include <stdlib.h>
double StringToNumber(char* str); void NumberToString(double i,char* buffer); double Calculate(char* str);
int main() { char test[]= {"(2*3)+4*2+(2*10+8)*(2-2)-2+5"}; printf("%f",Calculate(test)); return 0; }
double Calculate(char* str2) { char str[1024]; sprintf(str,"%s",str2); short size=strlen(str2)+1; char calcs[size*2][18]; unsigned char operat=0; unsigned char number=0; unsigned char count; short i; char numbers_op[]= {"^*/+-"}; unsigned char iii=0; unsigned char ii=0; short ai=0;
while (1) { //printf("%s\n",str); ////// Resetten der Variablen Start ////// number=0; operat=0; count=0; i=0; size=strlen(str); ////// Resetten der Variablen Ende //////
while (i<size) // Die Schleife durchläuft den kompletten Eingabe-String { if ((str[i]>47 && str[i]<58) || str[i]==46) // Wenn ein Zeichen zwischen AscII-Code 44 (=0) und 57 (=9) oder wenn ein Punkt (. für Komma) gefunden wurde // Dann gehört das zu einer Zahl und bekommt einen extra Platz in calcs[] { calcs[number][count]=str[i]; // Die Zahl bekommt einen Platz in dem Array calcs[] operat=0; // Die Zahl ist kein Operator (+-*/^) , also setzen wir operat zu 0 count++; } else if ( (str[i]>39 && str[i]<44) || str[i]==94 || str[i]==47 ||str[i]==45 ) // Wenn einer der Operatoren ()*+^/- gefunden wurde, dann ist die Bedingung wahr { if ((operat==1 || i==0) && (str[i]==45 || str[i]==43) ) // Wenn wir schoneinmal einen Operator gefunden haben oder wenn wir das // erste Zeichen in dem String überprüfen und wir einen Plus oder Minus Operator finden // dann muss der + bzw. - Operator zu einer Zahl gehören, z.b. // -12+-2 // bzw. 12--3 { calcs[number][count]=str[i]; // Unser Zeichen bekommt also den selben Platz wie unsere Zahl count++; } else // Ansonsten wenn der Operator nicht zu einer Zahl gehört { calcs[number][count]='\0'; count=0; number++; // Unser Operator bekommt den nächsten Platz in calcs calcs[number][count]=str[i]; calcs[number][count+1]='\0'; number++; // Der Operator steht alleine in calcs[number], es wird also gleich ein Schritt weitergezählt if (str[i]>41) operat=1; // Wir haben einen Operator gefunden +-*^/ , () zählen nicht als Operator
count=0;
}
} i++; }
calcs[number][count]='\0';
sprintf(str, ""); ii=0; while (ii<5) { i=0; while (i<number) // Eine Schleife, die durch alle unsere Operatoren/Zahlen läuft { if ((calcs[i][0]>47 && calcs[i][0]<58)||(calcs[i][1]>47 && calcs[i][1]<58)) // Wenn wir an diesem Platz des Arrays calcs eine Zahl haben, dann ist die Bedingung wahr // Wir überprüfen ob wir eine Zahl haben, indem wir uns nur das erste Zeichen anschauen // wenn das erste Zeichen eine Zahl ist, dann ist alles eine Zahl // Falls das erste Zeichen keine Zahl ist, kann es immernoch sein, dass wir es mit // einer vorzeichenbehafteten Zahl zu tun haben (z.b. -44) // Also müssen wir auch noch das 2. Zeichen überprüfen {
if (calcs[i+1][0]==numbers_op[ii] && calcs[i+2][0]!=NULL && ((calcs[i+2][0]>47 && calcs[i+2][0]<58)||(calcs[i+2][1]>47 && calcs[i+2][1]<58))) // calcs[i] muss eine Zahl sein und calcs[i+2] muss eine Zahl sein // Damit wir wissen was wir mit den beiden Zahlen machen müssen, // schauen wir uns an was calcs[i+1] ist. // Ist calcs[i+1] also ^ und calcs[i] eine Zahl und calcs[i+2] auch eine Zahl, // Dann können wir ruhig den Code ausführen lassen
// Wir lassen ^ zuerst überprüfen, da ^ die höchste Priorität hat. // danach kommt */ und dann +- { if (ii==0) NumberToString(pow(StringToNumber(calcs[i]),StringToNumber(calcs[i+2])),calcs[i]); else if (ii==1) NumberToString(StringToNumber(calcs[i])*StringToNumber(calcs[i+2]),calcs[i]); else if (ii==2) NumberToString(StringToNumber(calcs[i])/StringToNumber(calcs[i+2]),calcs[i]); else if (ii==3) NumberToString(StringToNumber(calcs[i])+StringToNumber(calcs[i+2]),calcs[i]); else if (ii==4) NumberToString(StringToNumber(calcs[i])-StringToNumber(calcs[i+2]),calcs[i]); calcs[i+2][0]='\0'; // Reset der Zahl, da wir sie schoneinmal verrechnet haben calcs[i+1][0]='\0'; // Reset der Zahl, da wir sie schoneinmal verrechnet haben } } else if(calcs[i][0]=='(') // Wir haben also an der Stelle calcs[i] keine Zahl, sondern eine geöffnete Klammer { if (((calcs[i+1][0]>47 && calcs[i+1][0]<58) || (calcs[i+1][1]>47 && calcs[i+1][1]<58)) && calcs[i+2][0]==')') // Wenn calcs[i+1] eine Zahl ist, dann sollten wir einmal überprüfen ob calcs[i+2] eine geschlossene Klammer ist // und ob zwischen der geöffneten Klammer (calcs[i]) und der Geschlossenen (calcs[i+2]) eine zahl ist, // Wenn dort nur eine Zahl ist, dann können wir die Klammern entfernen { calcs[i+2][0]='\0'; // Klammern werden entfernt calcs[i][0]='\0'; // Klammern werden entfernt } }
i++; } ii++; }
i=0; ii=0; ai=0;
while (ai<=1024) { str[ai]='\0'; ai++; } ai=0; while (i<=number) { ii=0; while (ii<10) { if (calcs[i][ii]!='\0') { str[ai]=calcs[i][ii]; // Es wird ein neuer Term gebildet, aus den vorhandenen ai++; } else break; calcs[i][ii]='\0'; // Resetten des Inhalts ii++;
} i++; } if (number<=2) break; // Wenn wir 2 oder weniger Nummern gefunden haben, dann wird unsere Schleife verlassen // Bei 2 Nummern reicht ein Durchgang und deswegen kann danach verlassen werden }
return StringToNumber(str); // returnt das Ergebniss
}
double StringToNumber(char* str) { return atof(str); }
void NumberToString(double i,char* buffer) { sprintf(buffer, "%f", i); }
|
|
|
12/12/2010, 21:04
|
#4
|
elite*gold: 7110
Join Date: Jun 2009
Posts: 28,905
Received Thanks: 25,407
|
Quote:
|
string calcs[str.length()*2];
|
Und das mich.
Ich meine wtf? Wie soll der Compiler da genug Platz für lokale Variablen holen, wenn du ein Array aus Strings machst, das die doppelte Anzahl an Elementen hat, wie der Parameterstring an Zeichen?
Er muss die Anzahl doch schon zur Compilezeit kennen.
Das müsstest du schon mit new (und bei C mit malloc) machen.
Oder ist mir da ein seltsames Sprachkonstrukt entgangen, sodass ich die Wirkung dieser Zeile missverstanden habe?
Quote:
short size=strlen(str2)+1;
char calcs[size*2][18];
|
Hier genau so.
Wie gesagt, meines Wissens kann der Compiler keine Arrays dynamisch alloziieren, da lokale Variablen auf dem Stack abgelegt werden, der eben statisch festgelegten Platz pro Routine bietet.
Bisher habe ich es immer so gelernt, dass man wie gesagt so etwas mit new/malloc machen muss; falls ich falsch liege (du sagst ja, jetzt funktioniert es), warum? o.O
|
|
|
12/12/2010, 22:06
|
#5
|
elite*gold: 42
Join Date: Jun 2008
Posts: 5,425
Received Thanks: 1,888
|
Quote:
Originally Posted by MrSm!th
Und das mich.
Ich meine wtf? Wie soll der Compiler da genug Platz für lokale Variablen holen, wenn du ein Array aus Strings machst, das die doppelte Anzahl an Elementen hat, wie der Parameterstring an Zeichen?
Er muss die Anzahl doch schon zur Compilezeit kennen.
Das müsstest du schon mit new (und bei C mit malloc) machen.
Oder ist mir da ein seltsames Sprachkonstrukt entgangen, sodass ich die Wirkung dieser Zeile missverstanden habe?
Hier genau so.
Wie gesagt, meines Wissens kann der Compiler keine Arrays dynamisch alloziieren, da lokale Variablen auf dem Stack abgelegt werden, der eben statisch festgelegten Platz pro Routine bietet.
Bisher habe ich es immer so gelernt, dass man wie gesagt so etwas mit new/malloc machen muss; falls ich falsch liege (du sagst ja, jetzt funktioniert es), warum? o.O
|
^this.
Das dürfte Fehler jenseits von gut und böse werfen ._.
|
|
|
12/13/2010, 20:43
|
#6
|
elite*gold: 77
Join Date: May 2008
Posts: 5,430
Received Thanks: 5,878
|
Quote:
Originally Posted by MrSm!th
Und das mich.
Ich meine wtf? Wie soll der Compiler da genug Platz für lokale Variablen holen, wenn du ein Array aus Strings machst, das die doppelte Anzahl an Elementen hat, wie der Parameterstring an Zeichen?
Er muss die Anzahl doch schon zur Compilezeit kennen.
Das müsstest du schon mit new (und bei C mit malloc) machen.
Oder ist mir da ein seltsames Sprachkonstrukt entgangen, sodass ich die Wirkung dieser Zeile missverstanden habe?
Hier genau so.
Wie gesagt, meines Wissens kann der Compiler keine Arrays dynamisch alloziieren, da lokale Variablen auf dem Stack abgelegt werden, der eben statisch festgelegten Platz pro Routine bietet.
Bisher habe ich es immer so gelernt, dass man wie gesagt so etwas mit new/malloc machen muss; falls ich falsch liege (du sagst ja, jetzt funktioniert es), warum? o.O
|
Zuerst: Das mit dem 2*size war ein Bug, Klammern hatten 2 Einträge gebraucht. In meiner geposteten Version ist das immernoch so, ich habe es aber bereits ausgebessert.
Ich bin mir nicht sicher warum es funktioniert, aber es funktioniert...
Ich will natürlich Fehler vorbeugen und wenn möglich, Fehlerquellen total eliminieren. Deswegen werde ich es auch mit malloc machen.
Es kann sein, dass es in meinem Beispiel funktioniert.
Denn der Eingabe-String hat ja eine feste Länge und dadurch kann der Compiler gleich die Größe des Arrays bestimmen, bei Eingaben könnte es Probleme geben.
|
|
|
12/13/2010, 20:53
|
#7
|
elite*gold: 7110
Join Date: Jun 2009
Posts: 28,905
Received Thanks: 25,407
|
Ich meine, rein technisch wäre es schon möglich, dass zumindest lokale Arrays dynamisch alloziiert werden, aber es widerspricht den Sprachregeln von C++ und mit globalen wäre das nicht möglich, deswegen würde es mich schon sehr verwundern, wenn es dein Compiler macht.
Das mit der Länge des Strings bezweifle ich auch irgendwie, da der Compiler doch noch nicht den Rückgabewert von std::string::length() kennen kann, nur weil du ihn statisch initialisierst (bei dem char array sollte es mit sizeof gehen, da es ja ein array ist, nur bei pointern geht das damit nicht, aber naja, dass es mit strlen geht, ist mir auch ein rätsel).
Also wirklich, dein Code verwirrt mich o.o
|
|
|
12/13/2010, 21:15
|
#8
|
elite*gold: 77
Join Date: May 2008
Posts: 5,430
Received Thanks: 5,878
|
Quote:
Originally Posted by MrSm!th
Ich meine, rein technisch wäre es schon möglich, dass zumindest lokale Arrays dynamisch alloziiert werden, aber es widerspricht den Sprachregeln von C++ und mit globalen wäre das nicht möglich, deswegen würde es mich schon sehr verwundern, wenn es dein Compiler macht.
Das mit der Länge des Strings bezweifle ich auch irgendwie, da der Compiler doch noch nicht den Rückgabewert von std::string::length() kennen kann, nur weil du ihn statisch initialisierst (bei dem char array sollte es mit sizeof gehen, da es ja ein array ist, nur bei pointern geht das damit nicht, aber naja, dass es mit strlen geht, ist mir auch ein rätsel).
Also wirklich, dein Code verwirrt mich o.o
|
Naja ich sagte ja reiner C-Code ist mir recht fremd und in C/C++ braucht man sehr selten new/malloc, das meiste macht man über Klassen (z.b. string o.ä.).
Quote:
Originally Posted by MrSm!th
Ich meine, rein technisch wäre es schon möglich, dass zumindest lokale Arrays dynamisch alloziiert werden, aber es widerspricht den Sprachregeln von C++ und mit globalen wäre das nicht möglich, deswegen würde es mich schon sehr verwundern, wenn es dein Compiler macht.
|
Tja ist eben ein guter/schlechter Compiler, kommt darauf an von welcher Seite man es sieht.
Ich habe den ganzen Code nocheinmal überarbeitet und eine "Interpret-Funkton" mit eingebaut, die im Grunde eine sehr einfache Skriptsprache ist, mit der man aber kleinere Sachen automatisieren kann.
Die Funktion Calculate unterstützt jetzt auch Konstante (Pi,Goldener Schnitt...) und man kann, falls nötig, noch zusätzliche Konstante über die Eingangsparamater setzen.
Die Funktion Calculate beherrscht nun auch XOR, Or, Modulo und And.
Btw. Wundert euch nicht, dass alle Arrays so "klein" sind, denn der gesamte genutzte Ram darf 4kB nicht übersteigen.
Ihr könnt die Arrays natürlich, wenn ihr die Funktionen auf einen Computer benutzt, vergrößern und somit auch größere Rechnungen genauer lösen.
PHP Code:
#include <stdio.h> #include <stdlib.h>
double StringToNumber(char* str); void NumberToString(double i,char* buffer); double Calculate(char* str2,char *y,char *z,char *a); void Intepret(char* str,double *zahl1,double *zahl2,double *zahl3); double Factorial(unsigned short d); void ReplaceAll(char *str,const char *str2,const char *str3);
int main() { //char test[]= {"(((pi)*2)+1)"}; char test[]= {"z=z+3;if{z<10} JMP1;if{z>11} JMP5;z=z*-1;z=z*2"};
double z1=0,z2=0,z3=0;
Intepret(test,&z1,&z2,&z3); printf("%f %f %f",z1,z2,z3); //printf("%f",Calculate("10^10","10^13","",""));
return 0; }
void Intepret(char* str,double* zahl1,double* zahl2,double* zahl3) { double erg=0; unsigned char count2=0; char y[42],bedingung=1; char z[42]; char a2[42]; char execute[16][64]; char temp[64]; short i=0,a=0,i2=0,count=0,sicherheit=0; if (str[strlen(str)-1]!=';') { str[strlen(str)]=';'; str[strlen(str)+1]='\0'; } while (i<strlen(str)) { if (str[i]==';') { execute[a][i2]='\0'; a++; i2=0; } else { execute[a][i2]=str[i]; i2++; } if (a>15) { break; a=15; } i++; } i2=0;
while (i2<a && sicherheit < 30000) { i=0; bedingung=1; while (i<strlen(execute[i2])-2) {
if ((execute[i2][i]=='i' || execute[i2][i]=='I')&&(execute[i2][i+1]=='f' || execute[i2][i+1]=='F' )) { count2=0; count=0; while (count<strlen(execute[i2])) { if (execute[i2][count]=='{') bedingung=1; else if (bedingung==1) { temp[count2]=execute[i2][count]; count2++; } count++; if (execute[i2][count]=='=') { temp[count2]='\0'; erg=Calculate(temp,y,z,a2); count2=0; count++; while (count<strlen(execute[i2])) { if (execute[i2][count]=='}') break; else { temp[count2]=execute[i2][count]; count2++; count++; }
} i=count; temp[count2]='\0'; if (erg==Calculate(temp,y,z,a2)) bedingung=1; else bedingung=0; break; } else if(execute[i2][count]=='>') { temp[count2]='\0'; erg=Calculate(temp,y,z,a2); count2=0; count++; while (count<strlen(execute[i2])) { if (execute[i2][count]=='}') break; else { temp[count2]=execute[i2][count]; count2++; count++; }
} i=count; temp[count2]='\0'; if (erg>Calculate(temp,y,z,a2)) bedingung=1; else bedingung=0; break;
} else if(execute[i2][count]=='<') { temp[count2]='\0'; erg=Calculate(temp,y,z,a2); count2=0; count++; while (count<strlen(execute[i2])) { if (execute[i2][count]=='}') break; else { temp[count2]=execute[i2][count]; count2++; count++; } } i=count; temp[count2]='\0'; if (erg<Calculate(temp,y,z,a2)) bedingung=1; else bedingung=0; break; } } }
if (bedingung==1) { if ((execute[i2][i]=='j' || execute[i2][i]=='J') && (execute[i2][i+1]=='m' || execute[i2][i+1]=='M') && (execute[i2][i+2]=='p' || execute[i2][i+2]=='P') ) { count=0; i=i+3; while (1) { if (execute[i2][i]=='\0') break; else { temp[count]=execute[i2][i]; i++; count++; } } temp[count]='\0'; i2=StringToNumber(temp)-2; break; } else if (execute[i2][i]=='y' || execute[i2][i]=='Y' ) { count=0; strcpy(temp,execute[i2]); while (1) { if (temp[count]=='=' && count>i) break; else { temp[count]=' '; count++; } } NumberToString(Calculate(temp,y,z,a2),y); *zahl1=StringToNumber(y); break; } else if (execute[i2][i]=='z' || execute[i2][i]=='Z' ) { count=0; strcpy(temp,execute[i2]); while (1) {
if (temp[count]=='=' && count>i) break; else { temp[count]=' '; count++; } } temp[count]=' '; NumberToString(Calculate(temp,y,z,a2),z); *zahl2=StringToNumber(z); break; } else if (execute[i2][i]=='a' || execute[i2][i]=='A' ) { count=0; strcpy(temp,execute[i2]); while (1) { if (temp[count]=='=' && count>i) break; else { temp[count]=' '; count++; } } temp[count]=' '; NumberToString(Calculate(temp,y,z,a2),a2); *zahl3=StringToNumber(a2); break; } }
i++; } sicherheit++; i2++; } }
double Calculate(char* str2,char *y,char *z,char *a) { char str[512]; sprintf(str,"%s",str2); short size=strlen(str2); char** calcs; calcs = (char **) malloc(size * sizeof(char *)); unsigned char original=size; short i; char numbers_op[]= {"^*/+-%&|X"}; unsigned char iii=0; unsigned char ii=0; unsigned char operat=0; unsigned char number=0; unsigned char count; short ai=0; if(NULL != calcs) { size++; ii=1408/size; iii=size-1; while(ai<iii) { calcs[ai] = (char *) malloc(ii * sizeof(char)); if(NULL == calcs[ai]){free(calcs[ai]);size=-1; break;} ai++; } if (size!=-1) {
while (1) { ////// Resetten der Variablen Start ////// number=0; operat=0; count=0; i=0; size=strlen(str); ////// Resetten der Variablen Ende //////
while (i<size) // Die Schleife durchläuft den kompletten Eingabe-String { if ((str[i]>47 && str[i]<58) || str[i]==46) // Wenn ein Zeichen zwischen AscII-Code 44 (=0) und 57 (=9) oder wenn ein Punkt (. für Komma) gefunden wurde // Dann gehört das zu einer Zahl und bekommt einen extra Platz in calcs[] { calcs[number][count]=str[i]; // Die Zahl bekommt einen Platz in dem Array calcs[] operat=0; // Die Zahl ist kein Operator (+-*/^) , also setzen wir operat zu 0 count++; } else if ( (str[i]>39 && str[i]<44) || str[i]==94 || str[i]==47 ||str[i]==45 || str[i]==37 || str[i]==88 || str[i]==38 || str[i]==124) // Wenn einer der Operatoren ()*+^/-% gefunden wurde, dann ist die Bedingung wahr { if ((operat==1 || i==0) && (str[i]==45 || str[i]==43) ) // Wenn wir schoneinmal einen Operator gefunden haben oder wenn wir das // erste Zeichen in dem String überprüfen und wir einen Plus oder Minus Operator finden // dann muss der + bzw. - Operator zu einer Zahl gehören, z.b. // -12+-2 // bzw. 12--3 {
calcs[number][count]=str[i]; // Unser Zeichen bekommt also den selben Platz wie unsere Zahl count++; operat=0; } else // Ansonsten wenn der Operator nicht zu einer Zahl gehört { calcs[number][count]='\0'; if (calcs[number][0]!='\0') number++; // Unser Operator bekommt den nächsten Platz in calcs calcs[number][0]=str[i]; calcs[number][1]='\0'; if (str[i]!=41)operat=1; // Wir haben einen Operator gefunden number++; // Der Operator steht alleine in calcs[number], es wird also gleich ein Schritt weitergezählt count=0;
} } else if((str[i]=='p' || str[i]=='P') && (str[i+1]=='i' || str[i+1]=='I')) { sprintf(calcs[number], "3.1415926535"); number++; operat=0; } else if((str[i]=='E' || str[i]=='e') && (str[i+1]=='m' || str[i+1]=='M') ) { sprintf(calcs[number], "0.5772156649"); number++; operat=0; } else if(str[i]=='e' || str[i]=='E') { sprintf(calcs[number], "2.7182818284"); number++; operat=0; } else if((str[i]=='g' || str[i]=='G') && (str[i+1]=='s' || str[i+1]=='S')) { sprintf(calcs[number], "1.6180339887"); number++; operat=0; } else if(str[i]=='b' || str[i]=='B') { sprintf(calcs[number], "1.9021605"); number++; operat=0; } else if((str[i]=='F' || str[i]=='f')&& (str[i+1]=='k' || str[i+1]=='K')) { sprintf(calcs[number], "4.6692016091"); number++; operat=0; } else if(str[i]=='y' || str[i]=='Y') { sprintf(calcs[number], "%s",y); number++; operat=0; } else if(str[i]=='z' || str[i]=='Z') { sprintf(calcs[number], "%s",z); number++; operat=0; } else if(str[i]=='a' || str[i]=='A') { sprintf(calcs[number], "%s",a); number++; operat=0; } i++; }
calcs[number][count]='\0';
sprintf(str, ""); ii=0; while (ii<sizeof(numbers_op)) { i=0; while (i<number) // Eine Schleife, die durch alle unsere Operatoren/Zahlen läuft { if ((calcs[i][0]>47 && calcs[i][0]<58)||(calcs[i][1]>47 && calcs[i][1]<58)) // Wenn wir an diesem Platz des Arrays calcs eine Zahl haben, dann ist die Bedingung wahr // Wir überprüfen ob wir eine Zahl haben, indem wir uns nur das erste Zeichen anschauen // wenn das erste Zeichen eine Zahl ist, dann ist alles eine Zahl // Falls das erste Zeichen keine Zahl ist, kann es immernoch sein, dass wir es mit // einer vorzeichenbehafteten Zahl zu tun haben (z.b. -44) // Also müssen wir auch noch das 2. Zeichen überprüfen {
if (calcs[i+1][0]==numbers_op[ii] && calcs[i+1][1]=='\0' && ((calcs[i+2][0]>47 && calcs[i+2][0]<58)||(calcs[i+2][1]>47 && calcs[i+2][1]<58))) // calcs[i] muss eine Zahl sein und calcs[i+2] muss eine Zahl sein // Damit wir wissen was wir mit den beiden Zahlen machen müssen, // schauen wir uns an was calcs[i+1] ist. // Ist calcs[i+1] also ^ und calcs[i] eine Zahl und calcs[i+2] auch eine Zahl, // Dann können wir ruhig den Code ausführen lassen
// Wir lassen ^ zuerst überprüfen, da ^ die höchste Priorität hat. // danach kommt */ und dann +- { if (ii==0) NumberToString(pow(StringToNumber(calcs[i]),StringToNumber(calcs[i+2])),calcs[i]); else if (ii==1) NumberToString(StringToNumber(calcs[i])*StringToNumber(calcs[i+2]),calcs[i]); else if (ii==2) NumberToString(StringToNumber(calcs[i])/StringToNumber(calcs[i+2]),calcs[i]); else if (ii==3) NumberToString(StringToNumber(calcs[i])+StringToNumber(calcs[i+2]),calcs[i]); else if (ii==4) NumberToString(StringToNumber(calcs[i])-StringToNumber(calcs[i+2]),calcs[i]); else if (ii==5) NumberToString(fmod(StringToNumber(calcs[i]),StringToNumber(calcs[i+2])),calcs[i]); else if (ii==6) NumberToString((long)(StringToNumber(calcs[i]))&(long)(StringToNumber(calcs[i+2])),calcs[i]); else if (ii==7) NumberToString((long)(StringToNumber(calcs[i]))|(long)(StringToNumber(calcs[i+2])),calcs[i]); else if (ii==8) NumberToString((long)(StringToNumber(calcs[i]))^(long)(StringToNumber(calcs[i+2])),calcs[i]); calcs[i+2][0]='\0'; // Reset der Zahl, da wir sie schoneinmal verrechnet haben calcs[i+1][0]='\0'; // Reset der Zahl, da wir sie schoneinmal verrechnet haben calcs[i+2][1]='\0'; // Reset der Zahl, da wir sie schoneinmal verrechnet haben calcs[i+1][1]='\0'; // Reset der Zahl, da wir sie schoneinmal verrechnet haben } } else if(calcs[i][0]=='(') // Wir haben also an der Stelle calcs[i] keine Zahl, sondern eine geöffnete Klammer { if (((calcs[i+1][0]>47 && calcs[i+1][0]<58) || (calcs[i+1][1]>47 && calcs[i+1][1]<58)) && calcs[i+2][0]==')') // Wenn calcs[i+1] eine Zahl ist, dann sollten wir einmal überprüfen ob calcs[i+2] eine geschlossene Klammer ist // und ob zwischen der geöffneten Klammer (calcs[i]) und der Geschlossenen (calcs[i+2]) eine zahl ist, // Wenn dort nur eine Zahl ist, dann können wir die Klammern entfernen { calcs[i+2][0]='\0'; // Klammern werden entfernt calcs[i][0]='\0'; // Klammern werden entfernt } }
i++; } ii++; }
i=0; ii=0; ai=0;
while (ai<=512) { str[ai]='\0'; ai++; } ai=0; while (i<=number) { ii=0; while (ii<10) { if (calcs[i][ii]!='\0') { str[ai]=calcs[i][ii]; // Es wird ein neuer Term gebildet, aus den vorhandenen ai++; } else break; calcs[i][ii]='\0'; // Resetten des Inhalts ii++;
} i++; } //printf("%s\n",str); if (number<=2) break; // Wenn wir 2 oder weniger Nummern gefunden haben, dann wird unsere Schleife verlassen // Bei 2 Nummern reicht ein Durchgang und deswegen kann danach verlassen werden }
return StringToNumber(str); // returnt das Ergebniss } } else free(calcs); ii=0; while (ii<original) { free(calcs[ii]); ii++; } free(calcs); }
double StringToNumber(char* str) { return atof(str); }
void NumberToString(double i,char* buffer) { sprintf(buffer, "%f", i); } // ==> IntToString(int i)
double Factorial(unsigned short d) { double d2=1; while (d>0) { d2*=d; d--; } return d2; }
|
|
|
12/13/2010, 21:19
|
#9
|
elite*gold: 7110
Join Date: Jun 2009
Posts: 28,905
Received Thanks: 25,407
|
Quote:
Originally Posted by Shadow992
Naja ich sagte ja reiner C-Code ist mir recht fremd und in C/C++ braucht man sehr selten new/malloc, das meiste macht man über Klassen (z.b. string o.ä.).
|
lol hast du ne ahnung 
klar, man braucht nix dynamisches, gibt ja klassen von anderen für alles ;OO
Quote:
Tja ist eben ein guter/schlechter Compiler, kommt darauf an von welcher Seite man es sieht.
|
ich glaube nicht, dass er es wirklich tut, welchen hast du?
|
|
|
12/13/2010, 21:24
|
#10
|
elite*gold: 77
Join Date: May 2008
Posts: 5,430
Received Thanks: 5,878
|
Quote:
Originally Posted by MrSm!th
lol hast du ne ahnung 
klar, man braucht nix dynamisches, gibt ja klassen von anderen für alles ;OO
|
Ganz ehrlich, darüber bin ich sehr froh, dass viele Klassen mit new/malloc arbeiten ist klar, aber ich als Benutzer merke davon recht wenig. :P
Quote:
Originally Posted by MrSm!th
ich glaube nicht, dass er es wirklich tut, welchen hast du?
|
MinGw, müsste eine "abgespeckte" GNU GCC Version sein (wenn ich richtig informiert bin). Ich habe den bei Code-Blocks ,sozusagen, mitgelieferten Compiler genommen. Der hat mir bisher immer sehr gute Ergebnisse geliefert.
|
|
|
12/13/2010, 21:38
|
#11
|
elite*gold: 42
Join Date: Jun 2008
Posts: 5,425
Received Thanks: 1,888
|
Quote:
Originally Posted by Shadow992
Btw. Wundert euch nicht, dass alle Arrays so "klein" sind, denn der gesamte genutzte Ram darf 4kB nicht übersteigen.
|
Spielt da wer mit Mikrocontrollern rum? ^.^
|
|
|
12/13/2010, 21:56
|
#12
|
elite*gold: 77
Join Date: May 2008
Posts: 5,430
Received Thanks: 5,878
|
Quote:
Originally Posted by MoepMeep
Spielt da wer mit Mikrocontrollern rum? ^.^
|
***, ich bin an die ganze Sache eigentlich vor knapp einem halben Jahr mit der Einstellung: "Ich mache einen Roboter." rangegangen, aber mir fehlen einfach die physikalischen Verständnisse für die ganzen Vorgänge (SteUp-Wandler,Spannungsverstärker[invertierend, nicht invertierend]...).
Mit dem bisschen Schul-Physik, kam ich da nicht weit, also dachte ich mir ich fang mit etwas "Leichtem" an. Nachdem ich überlegt habe, was ich machen könnte bin ich durch Zufall auf so ein Anfänger-Tutorial für irgendeine Sprache gestoßen und da hieß es dann: "Wir machen etwas einfaches, einen Taschenrechner.".
Und da ich den C/C++ Code von dem mathematischen Parser noch hatte, dachte ich mir ich mache mir einen Taschenrechner, der auch etwas fordert (Softwaremäßg, die Hardware ist in diesem Fall ja relativ einfach).
So far...
Btw. Ich bin bei dem maximal belegten Platz für den Ram (für Variablen) auf ca 3.5kB gekommen, stimmt das?
|
|
|
All times are GMT +1. The time now is 18:34.
|
|