Taschenrechner: Keine Eingabe möglich
-
#include <stdio.h> #include <stdlib.h> #include <ctype.h> #define MAXOP 100 #define MAXVAL 100 #define NUMBER '0' int getop(char []); void push(double); double pop(void); int getch(void); void ungetch(int); int main(int argc, char* argv[]) { int type; double op2; char s[MAXOP]; while ((type = getop(s)) != EOF) { switch(type) { case NUMBER: push(atof(s)); break; case '+': push(pop() + pop()); break; case '*': push(pop() * pop()); break; case '-': op2 = pop(); push(pop() - op2); break; case '/': op2 = pop(); if (op2 != 0.0) push(pop() / op2); else printf("error: zero divisor\n"); break; case '%': op2 = pop(); if (op2 != 0.0) push(fmod(pop(), op2)); else printf("error: zero divisor\n"); break; case '\n': printf("\t%.8g\n", pop()); break; default: printf("error: Unknown command %s\n", s); break; } } return 0; } void push(double f) { int sp; char val[MAXVAL]; if (sp < MAXVAL) val[sp++] = f; else printf("error: stack full, can't push %g\n", f); } double pop(void) { int sp; char val[MAXOP]; if (sp > 0) return val[--sp]; else { printf("error: stack empty\n"); return 0.0; } } int getop(char s[]) { int i, c; while ((s[0] = c = getch()) == ' ' || c == '\t') ; s[1] = '\0'; if (!isdigit(c) && c != '.') return c; i = 0; if (isdigit(c)) while (isdigit(s[++i] = c = getch())) ; if (c == '.') while (isdigit(s[++i] = c= getch())) ; s[i] = '\0'; if (c != EOF) ungetch(c); return NUMBER; }
Ich kann am Anfang keine Zahlen eingeben... Woran liegt das denn ?
-
Also ich kann nur Sonderzeichen eingeben und dann bekomm ich die Fehlermeldung, dass der "stack" voll ist !!!
-
Schmeiß hald mal deinen Debugger an.
-
Mein Debugger gibt mir keinen Fehler aus.... daher dachte ich auch am Anfang, das alles gehen müsste !1!
-
Ich wusste gar nicht, dass ein Debugger Fehler ausgeben kann
.
Ich meinte damit auch eher, du solltest dein Programm, speziell deine Eingabefunktion, Schritt für Schritt mit dem Debugger durchgehen, um festzustellen, woran es scheitert, dass du keine Zahlen eingeben kannst.
-
return val[--sp];
Hier bricht er immer ab und lässt nicht zu, dass es weiter geht. Die Eingabe von Zahlen wird gar nicht berücksichtigt, was ich daran gesehen habe, dass dabei keine Reaktion innerhalb des Quellcodes geschehen ist.
-
Ok ich seh schon was das Problem ist.
Mach dir mal Gedanken darüber was du mit sp anstellst und welchen Wert es hat, wenn du es verwendest.
Außerdem solltest du dir mal Gedanken darüber machen wie lange lokale Variablen gültig sind ;).
-
Ich lese gerade etwas von einem rudimentären Taschenrechner .... Gibts da Beispiele für solch einen Taschenrechner im Netz ?
-
Ähm, hast du deinen Fehler jetzt schon gefunden oder brauchst du noch einen direkteren Hinweis?
-
Ne ich hab noch keine Lösung gefunden, aber ich hab eine alternative Lösung gefunden:
#include <stdio.h> int main () { int zahl1; int zahl2; int zeichen; printf ("Bitte geben Sie Ihre erste Zahl ein: \n"); scanf ("%d", &zahl1); printf ("Nun waehlen Sie bitte den Zeichenerator aus -> 1:+ 2:- 3:* 4:/ \n"); scanf ("%d", &zeichen); printf ("Bitte geben Sie Ihre zweite Zahl ein: \n"); scanf ("%d", &zahl2); switch (zeichen) { case 1: printf ("Ihre Aufgabe lautet somit %d + %d = %d\n", zahl1, zahl2, zahl1 + zahl2); break; case 2: printf ("Ihre Aufgabe lautet somit %d - %d = %d\n", zahl1, zahl2, zahl1 - zahl2); break; case 3: printf ("Ihre Aufgabe lautet somit %d * %d = %d\n", zahl1, zahl2, zahl1 * zahl2); break; case 4: printf ("Ihre Aufgabe lautet somit %d / %d = %d\n", zahl1, zahl2, zahl1 / zahl2); break; } return 0; }
Damit geht es auch, aber ich setze mich gleich nochmal dran, damit die andere Lösung auch funktioniert und wenn ich Fragen habe, dann frag ich nochmal nach !
-
Ich frage mich, warum bei der Alternative, das mit 1, 2, usw. für die Operatoren verwendet wird. Da braucht man doch nur das Zeichen (%c) einlesen und das Zeichen abfragen
.
Außerdem ist es buggy. Gib mal folgendes Beispiel ein:
10 / 0Zu deiner ersten Lösung. Schau dir nochmal deine Funktionen pop() und push() an. Du verwendest dort eine LOKALE Variable (sp) und außerdem wird sie nirgendwo initialisiert! Die zweite lokale Variable (val) gibt mir auch zu denken. Ich schätze das musst du nochmal überdenken.
Wie schon gesagt, denk nochmal nach, wie lange lokale Variablen gültig sind. Wenn du es nicht weißt, dann frag einfach nach :).
-
Ich erarbeite derzeit nochmal eine andere Lösung:
#include <stdio.h> #include <ctype.h> #define MAXLINE 100 double atof(char s[]); int getline(char line[], int max); int main(int argc, char* argv[]) { double sum, atof(char []); char line[MAXLINE]; sum = 0; while (getline(line, MAXLINE) > 0) printf("\t%g\n", sum += atof(line)); return 0; } double atof(char s[]) { double val, power; int i, sign; for (i = 0; isspace(s[i]); i++) ; sign = (s[i]) == '-' ? -1 : 1; if (s[i] == '+' || s[i] == '-') i++; for (val = 0.0; isdigit(s[i]); i++) val = 10.0 * val + (s[i] - '0'); if (s[i] == '.') i++; for (power = 1.0; isdigit(s[i]); i++) { val = 10.0 * val + (s[i] - '0'); power *= 10.0; } return sign * val / power; } int getline(char line[], int maxline) { int i, c; if(c == '\n') { line[i] = c; ++i; } line[i] = c; if (c == '\t') { line[i] = c; ++i; } else line[i] = c; return c; }
Es gibt keine Fehlerangabe, aber ich bekomme beim Programmablauf einen Fehler, der auf eine Nutzung von Speicherplatz zurückzuführen ist.
Ich benutze also einen Speicherbereich, den ich gar nicht benutzen darf !
-
Gleiches Problem wie bei pop() und push().
Du verwendest Variablen ohne sie zu initialisieren!
In der Funktion getline() definierst du i und c. Was steht denn deiner Meinung nach in i und c drin, wenn du sie das erste mal verwendest??
-
Nach meiner Ansicht hat es den Grund, dass der Wert von c und i in der Funktion von "getline" irgendwie nicht stimmt.
Selbst mit dem Debugger komm ich nicht genau auf die Spur von dem Fehler und kann auch daher nicht so genau eine Aussage machen !;): wir haben gleichzeitig eben geschrieben
int getline(char line[], int maxline) { int i, c; c = 0; i = 0; if(c == '\n') { line[i] = c; ++i; } line[i] = c; if (c == '\t') { line[i] = c; ++i; } else line[i] = c; return c; }
Diese Version beinhaltet eine Initialisierung, aber das Problem dabei ist auch, dass ich gar keine Eingabe machen kann.
Ergo kann ich also auch keine Zahlen eingeben, die der Taschenrechner berechnen soll. Mit der Initialisierung der getline-Funktion wird eine Endlosschleife erzeugt die immer Nullen ausgibt.
-
lol?
Ist der Code dein Ernst?
int getline(char line[], int maxline) { int i, c; c = 0; i = 0; // ... if(c == '\n') // c ist 0! // ... if (c == '\t') // c ist 0!
-
Gut jetzt kannst du zumindest schon mal keine Speicherverletzung mehr kriegen. In uninitialisierten Variablen steht übrigens irgendein Zufallswert oder besser gesagt der Wert, der an der Speicherstelle steht beim Reservieren des Speichers.
Um jetzt deine Eingabefunktion zu vollenden musst du eine Funktion aufrufen, die ein Zeichen von der Tastatur liest. Erraten was du willst, kann der Compiler nämlich noch nicht ;). Das Zeichen, dass du von der Tastatur einliest musst dann natürlich c zuweisen.
Aja und die Funktion getline() an sich solltest du auch nochmal überarbeiten. Im Endeffekt sollte es so aussehen:
Die Funktion liest ein Zeichen von der Tastatur ein.
Wenn das Zeichen ein Zeilenumbruch ist, dann wird die Eingabe beendet.
Wenn das Zeichen kein Steuerzeichen ist, dann wird es in den übergebenen Buffer geschrieben. (Das nächste Zeichen muss dann an die nächste Stelle geschrieben werden!) Dabei erhöht sich der Zeichenzähler.
Wenn der Zeichenzähler das Maximum erreicht, wird die Eingabe beendet. (Wir wollen ja keinen Bufferoverflow verursachen ;))Rückgabewert ist die Anzahl der eingelesenen Zeichen.
-
So ich hab jetzt getline nochmal anders geschrieben, weil mir die Funktion auch nicht so wirklich gepasst hat.
int getline(char line[], int maxline) { int c, i; for (i = 0; i < MAXLINE-1 && (c = getchar()) != EOF && c != '\n'; ++i) line[i] = c; if (c == '\n') { line[i] = c; ++i; } line[i] = '\0'; return i; }
Ich kann nun mit diesem rudimentären Taschenrechner + und - berechnen, aber für mehr langt es derzeit noch nicht.
-
So nachdem nun der normale Taschenrechner geht, muss ich mal sehen, wie ich die sonstigen Funktionen darin einbaue.
Funktionen, die der Taschenrechner beherrschen soll:
- Plus, Minus
- *, /
- Wurzel und Quadrat
- Sinus und Cosinus
- Eingabe von Buchstaben
-
cHillb3rT schrieb:
int getline(char line[], int maxline) { int c, i; for (i = 0; i < MAXLINE-1 && (c = getchar()) != EOF && c != '\n'; ++i) line[i] = c; if (c == '\n') { line[i] = c; ++i; } line[i] = '\0'; return i; }
Du weißt aber schon, dass ein Unterschied zwischen maxline und MAXLINE besteht, oder??
* und / dürften kein Problem sein. Bedenke allerdings, dass du bei / eine bestimmte Abfrage einbauen musst, sonst stürzt dir das Programm ab!
AJ schrieb:
Außerdem ist es buggy. Gib mal folgendes Beispiel ein:
10 / 0
-
Ich arbeite jetzt gerade an der Version vom Anfang....
Da hatte ich ja das Problem, das ich nicht mal Zahlen eingeben konnte... nun geht das, aber ich bekomme gesagt, dass mein "Stack" zu hoch ist.Wahrscheinlich hängt das mit der lokalen Variablen zusammen und nun frag ich mal in die Runde, wie genau man das Problem beheben kann bzw könnte !