C++ lineare, qudratische Funktionen ganz einlesen

2 Antworten

Am bequemsten wäre die Eingaben von beliebig vielen Tripeln a₂ a₁ a₀ mit Whitespace oder Semikolon getrennt und mit EOF terminiert (^D unter Unixen, ^Z unter Windows). Statt einer lästigen Abfrage "linear/quadratisch" könnte man dann einfach a₂=0 setzen. also etwa:

zwerg@home ~$square
Koeffizienten (a₂ a₁ a₀)? 0 2.5 -5
lineare Gleichung +2.5 x -5.0 = 0: x=2.0
Koeffizienten (a₂ a₁ a₀)? -1 -2 0 1 2 1
quadratische Gleichung -1.0 x² -2.0 x +0.0 = 0: x₁=-2.0,  x₂=0.0
quadratische Gleichung  +1.0 x² +2.0 x +1.0 = 0: x₁=-1.0,  x₂=-1.0
Koeffizienten (a₂ a₁ a₀)? ^D
zwerg@home ~$

Das wäre sehr einfach zu programmieren und funktioniert auch mit Pipes oder Eingabe aus Dateien.

Wenn Du wirklich eine textuell eingegebene Formel auswerten möchtest, dann musst Du einen Parser dafür schreiben. Du wirst Dir damit eine Menge Mehraufwand ggü. der "Trivialabfrage" ins Haus holen. Denn wenn Du einem Benutzer eine freie Eingabemöglichkeit erlaubst, dann kann der halt auch andere Sachen eingeben wie z. B.

m*x+k*x-3*a*x²

Du müsstest sowas also überhaupt erstmal in Deinem Programm "verstehen", und dann auch noch die eingebene Formel normalisieren.

Wenn es sich nur um eine Hausaufgabe o. ä. handelt, dann würde ich mir den Streß nicht machen.

Wenn es Dich aber privat interessiert, dann solltest Du Dich mit Parserbau ganz allgemein beschäftigen.

DerZwerg666 
Fragesteller
 10.05.2015, 14:51

Ich hatte mir in der Theorie gedacht das man das mit nem char array z.B. lösen könnte. Ich lese einfach alles ein und dann wird der "String"  "zerlegt" und dann werden die jeweiligen werte extra Variabeln zugewiesen und damit gerechnet. Nur ich hab nicht die geringste Ahnung wie ich das Anstellen soll^^ Aber ich gucke mir trotzdem mal den Parserbau an, kann ja nicht schaden :D

0
dan030  10.05.2015, 14:59
@DerZwerg666

Du kannst entweder aus einem String (bzw. char-Array) die Eingabe auslesen. Oder etappenweise mit scanf() parsen. Oder mit "<<" den Input "einstreamen".

Welchen Weg auch immer Du gehst: es ist nicht mit 50 Zeilen Code getan. Einen Parser zu schreiben, der die möglichen Eingaben zumindest so leidlich versteht, und insbesondere auch bei nicht verstandenen Eingaben korrekte Fehlermeldungen gibt, ist eine größere Sache. Man kommt da schnell auf 1200-1500 Codezeilen. Bedenke, dass der Benutzer ggf. auch anfangen wird, Klammern zu setzen, Du musst "Punktrechnung vor Strichrechnung" korrekt auswerten usw. D. h. Du musst zweischrittig arbeiten: erst den Rotz von der Inputseite einlesen, einen Parserbaum aufbauen. Und dann im zweiten Schritt diesen Baum normalisieren, um die Ergebnisse der eigenlichen Verarbeitung zuzuführen.

1
DerZwerg666 
Fragesteller
 10.05.2015, 15:12
@dan030

Im Vergleich zu meinen Klassenkameraden sind meine Code's meist mehr als doppelt so lang, da ich wirklich wie die immer sagen "jeden sch***" bedenke, Also ausdauer sowas zu schreiben hab ich auf jeden Fall. Ich bin in der Schule eigentlich an den Stoff der im Unterricht besprochen wurde gebunden nur bei dieser Projektarbeit nicht, diese zählt aber 50% der Note. Wenn du lusten und Zeit hast können wir uns über Skype oder Ts austauschen und du kannst mir nen paar Tipps noch geben.

0
DerZwerg666 
Fragesteller
 10.05.2015, 15:37

Ne Moment mal ich merke gerade das du falsch verstanden hast was ich tuen möchte. Der Anwender wird vorher gefragt welches von beiden er machen will. Es wird wenn er lineare Funktionen auswählt die Syntax m*x+b vorgegeben, dann gibt er die Funktion nach dem Schema ein und dann werden die Werte den jeweiligen Variabeln zugewiesen. Wenn er da nur Murks hinschreibt oder eine Falsche Syntax benutzt soll eine Fehlermeldung kommen. Also er gibt NICHT einfach eine Formel ein und das Programm guckt was das für eine ist.

0
dan030  10.05.2015, 15:57
@DerZwerg666

Naja gut, wenn Dir das ausreicht, dann kann man sich da deutlich einfacher durchhangeln.

Beispiel: Formel soll in der Form "m*x+c" eingegeben werden, wobei der Benutzer "m" und "c" jeweils als Zahl eingeben muss. "c" darf weggelassen werden, also eine Eingabe nur "m*x" ist zulässig. Leerzeichen werden überlesen.

Das könnte man folgendermaßen implementieren so als Gerüst und ungestetet hier mal reingehackt:


const char *parse_linear(const char *formel,double *m,double *c)
{
double tempwert;
char *delim;

if (strchr("-0123456789",*formel)==NULL || !*formel)
return "Leerstring, oder Wert für m nicht numerisch";

while (*formel==' ' || *formel=='\t') formel++;

*m=strtod(formel,&formel);

while (*formel==' ' || *formel=='\t') formel++;

if (*formel!='*')
return "erwarte '*' nach Wert für m";
formel++;
while (*formel==' ' || *formel=='\t') formel++;
if (*formel!='x')
return "erwarte '*x' nach Wert für m";
formel++;
while (*formel==' ' || *formel=='\t') formel++;

if (!*formel) {
/* "+c" fehlt */
*c=0;
return NULL;
}

if (*formel!='+' && *formel!='-')
return "Syntaxfehler im Linearanteil";
if (formel=='+') {
formel++;
while (*formel==' ' || *formel=='\t') formel++;
}

if (strchr("-0123456789",*formel)==NULL || !*formel) return "Leerstring, oder Wert für c nicht numerisch";

*c=strtod(formel,&formel);
while (*formel==' ' || *formel=='\t') formel++;
if (*formel)
return "nach Wert für c keine weiteren Zusätze erlaubt";

/* alles ok */
return NULL;
}

Funktion gibt const char * zurück, NULL im Ok-Fall, falls non-NULL kommt die Fehlermeldung.

Das ist natürlich Parsen mit der Holzhammermethode. Man kann sowas auch schöner machen (z. B. die Space-Überspringer in eine skipspace()-Funktion auslagern etc.).


0
dan030  10.05.2015, 16:00
@dan030

Nachtrag: sehe gerade, die lokalen Variablen "tempwert" und "delim" brauchen wir ja gar nicht. :-)

0
DerZwerg666 
Fragesteller
 10.05.2015, 16:46
@dan030

So besten dank erstmal, noch steige ich da nicht ganz durch, mein Compiler meckert bei dem Programm rum :D vlt kriege ich es ja hin, hab ja jetzt ne "denkvorlage"

0