Taschenrechner: Keine Eingabe möglich



  • 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 !



  • Also ich bezweifle, dass deine paar Variablen den Stack sprengen könnten. Hast du dran was verändert? Zeig bitte mal den aktuellen Stand.



  • Das ist derzeit der Stand:

    #include <stdio.h>
    #include <stdlib.h>
    #include <ctype.h>
    
    #define MAXOP 100
    #define NUMBER '0'
    #define BUFSIZE 100
    
    int getop(char []);
    void push(double f);
    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[MAXOP];
      if (sp < MAXOP)
        val[sp++] = f;
      else
        printf("error: stack full, can't push %g\n", f);
    }
    
    double pop(void)
    {
      int sp = 0;
      double 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;
    }
    
    int getch(void)
    {
      char buf[BUFSIZE];
      int bufp = 0;
      return (bufp > 0) ? buf[--bufp] : getchar();
    }
    
    void ungetch(int c)
    {
      char buf[BUFSIZE];
      int bufp = 0;
      if (bufp >= BUFSIZE)
        printf("ungetch: Too many characters\n");
      else
        buf[bufp++] = c;
    }
    


  • die getop-Funktion wurde weiter bearbeitet von mir:

    int getop(char s[])
    {
      int i, c;
      while ((s[0] = c = getch()) == ' ' || c == '\t')
      ;
        s[1] = '\0';
        i = 0;
        /* Wenn "c" kein Punkt ist, dann wird der Wert von
        c zurückgegeben und "i" auf Null gesetzt. */
        if (!isdigit(c) && c != '.' && c != '-')
          return c;
          if (c == '-')
            if (isdigit(c = getchar()) || c == '.')
              s[++i] = c;
            else
            {
              if (c != EOF)
                ungetch(c);
              return '-';
            }
          /* Man sammelt nun den ganzzahligen Teil vor einem möglichen bestehenden
          Punkt ein */
          if (isdigit(c))
            while (isdigit(s[++i] = c = getch()))
              ;
            /* Wenn "c" ein Punkt ist wird ab diesem Punkt dann der Dezimalbereich
            eingespeichert. Wenn die obere Bedingung erfüllt ist, dann ist das Ende des Wortes
            erreicht. Danach wird noch überprüft ob es auch das Ende der Eingabe ist. Wenn
            es das Ende des Wortes ist, dann wird die Konstantenvariable NUMBER zurückgegen, die
            den Wert 0 besitzt und somit wieder den Anfang eines Wortes markiert. Wenn es das
            Ende der Eingabe ist übernimmt die Funktion ungetch die Verarbeitung von "c" */
            if (c == '.')
              while (isdigit(s[++i] = c = getch()))
              ;
              s[i] = '\0';
              if (c != EOF)
                ungetch(c);
              return NUMBER;
    }
    


  • Stand nach einer Stunde programmieren:
    - Egal welche Zahl ich eingebe, es wird mir angezeigt, dass der "stack" voll ist.
    - Es wird aufgrund dieser Tatsache keine Rechenoperation durchgeführt

    Hat einer von euch eine Idee, was falsch sein kann ?!?



  • Ok, ich glaube das ist wirklich ein hartnäckiges Problem, aber nur, wenn eine der beiden folgenden Fehlermeldungen auftritt:
    error: stack empty
    error: stack full, can't push ...

    🤡 🙄

    Ich hab dir eigentlich schon hundertmal ("leicht" übertrieben) gesagt, dass deine Variablen sp und val LOKAL sind und dass sp nicht INITIALISIERT ist (mittlerweile wenigstens bei pop).
    Es kann so einfach nicht funktionieren. So wie du es vorhast, muss sp und val global sein und sp muss unbedingt mit 0 initialisiert sein!
    Die bessere Variante wäre natürlich, dass du die Variablen als Parameter übergibst, allerdings ändert das nichts daran, dass sp mit 0 initialisiert werden muss; in jedem Fall.



  • so den Gedanken mit den globalen Variablen hatte ich auch, aber da kam mein Chef und meinte zu mir, dass man das nicht so macht.
    Daher kann ich das nicht so machen, da der Chef ja drüber guckt und das prüft und wenn ich es dann trotzdem so mache, muss ich wieder von vorne anfangen !



  • Darum hab ich ja auch das hier geschrieben:

    AJ schrieb:

    Die bessere Variante wäre natürlich, dass du die Variablen als Parameter übergibst, allerdings ändert das nichts daran, dass sp mit 0 initialisiert werden muss; in jedem Fall.

    Du musst deine zwei Variablen (sp und val) also in main() lokal definieren und als Parameter an push() und pop() übergeben. Allerdings die Adresse! Also müssen die Parameter bei der Funktion Zeiger sein.

    Ein Aufruf würde dann in etwa so aussehen:

    ...
    pop(&val, &sp);
    ...
    

    Ich gebe dir den guten Rat, dass du dich erstmal noch besser in die Grundlagen von C (oder überhaupt der Programmierung) einarbeitest, ansonsten wirst du das nie gescheit hinkriegen. Dein Chef sollte Verständnis dafür zeigen. Schließlich will er sicher, dass du die dir gestellten Aufgaben auch korrekt löst und nicht irgendwelchen Kunddelmuddel einbaust.



  • Ja ich arbeite derzeit seit 2 Monaten mit C und erlerne erst die Grundsachen gerade, aber ab un zu denk ich halt, dass ich den Kram verstanden habe, aber dann ist es wieder nicht so.
    Die Gefährlichkeit des Halbwissens hängt mir da noch nach. Delphi hab ich ja schon lange Zeit mal in der Schule gemacht, aber das ist wieder anders aufgebaut, als C.



  • Dann versuch am besten mal aus deinem Halbwissen zumindest ein Dreiviertelwissen zu machen ;).


Anmelden zum Antworten