lolamontes69

K+R Exercise4_3

Sep 7th, 2014
239
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 4.82 KB | None | 0 0
  1. #include <stdio.h>
  2. #include <stdlib.h> /*for atof() */
  3. #include <ctype.h>
  4.  
  5. #define MAXOP   100 /* max size of operand or operator */
  6. #define MAXVAL  100 /* maximum depth of val stack      */
  7. #define NUMBER  '0' /* signal that a number was found  */
  8. #define BUFSIZE 100 /* buffer for ungetch              */
  9.  
  10. int getop(char s[]);
  11. void push(double f);
  12. double pop(void);
  13. int getch(void);
  14. void ungetch(int);
  15.  
  16.  
  17. int sp = 0;         /* Next free stack position        */
  18. double val[MAXVAL]; /* value stack                     */
  19. char buf[BUFSIZE];
  20. int bufp = 0;       /* next free position in buffer    */
  21.  
  22.  
  23. /* Reverse Polish calculator */
  24. main()
  25. {
  26.     int type;
  27.     double op2;
  28.     double mod;
  29.     char s[MAXOP];
  30.  
  31.     while((type = getop(s)) != EOF) {
  32.         switch(type) {
  33.         case NUMBER:
  34.             push(atof(s));         // Add number to stack
  35.             break;
  36.         case '+':
  37.             push(pop() + pop());   // pop last number from stack and add to previous
  38.             break;                 // number from stack then add to stack as last item
  39.         case '*':
  40.             push(pop() * pop());   // as above with *
  41.             break;
  42.         case '-':                  // pop last number from stack save as op2
  43.             op2 = pop();           // pop previous number from stack
  44.             push(pop() - op2);     // otherwise would produce op2 - pop()
  45.             break;                 // and push to stack replacing them
  46.         case '/':
  47.             op2 = pop();           // as for '-' but with an errorcheck for
  48.             if(op2!=0.0)           // division by zero
  49.                 push(pop()/op2);
  50.             else
  51.                 printf("error: zero divisor\n");
  52.             break;
  53.         case '\%':
  54.             op2 = pop();            // as for '-' but with an errorcheck for
  55.             mod = pop();            // % cannot be applied to float or double
  56.             if(op2!=0.0) {          // so do the math here instead.
  57.                 if(mod>0 && op2>0) {
  58.                     while(mod-op2>=0)
  59.                         mod = mod - op2;
  60.                 }
  61.                 else if(mod<0 && op2>0) {
  62.                     mod = mod-mod-mod;
  63.                     while(mod-op2>=0)
  64.                         mod = mod - op2;
  65.                 }
  66.                 else if(mod<0 && op2<0) {
  67.                     mod = mod-mod-mod;
  68.                     op2 = op2-op2-op2;
  69.                     while(mod-op2>=0)
  70.                         mod = mod - op2;
  71.                     mod = mod-mod-mod;
  72.                 }
  73.                 else if(mod>0 && op2<0) {
  74.                     op2 = op2-op2-op2;
  75.                     while(mod-op2>=0)
  76.                         mod = mod - op2;  
  77.                     mod = mod-mod-mod;
  78.                 }
  79.                 push(mod);
  80.             }
  81.             else
  82.                 printf("error: zero divisor\n");
  83.             break;
  84.         case '\n':                      // if end of equation pop last item from stack
  85.             printf("\t%.8g\n", pop());  // aka the answer
  86.             break;
  87.         default:
  88.             printf("error: unknown command %s\n", s);  // None of the above
  89.             break;                                     // You dun goofed
  90.         }
  91.     }
  92.     return 0;
  93. }
  94.  
  95. /* push: push f onto value stack */
  96. void push(double f)
  97. {
  98.     if(sp < MAXVAL)
  99.         val[sp++] = f;     // Add item as stack[sp] then increment sp
  100.     else
  101.         printf("error: stack full, cant push %g\n", f);
  102. }
  103.  
  104. /* pop: pop and return top value from stack */
  105. double pop(void)
  106. {
  107.     if(sp > 0)
  108.         return val[--sp];   // return last item in stack first decrementing sp
  109.     else {
  110.         printf("error: stack empty\n");
  111.         return 0.0;
  112.     }
  113. }
  114.  
  115. /* getop: get next character or numeric operand */
  116. int getop(char s[])
  117. {
  118.     int i, c;
  119.  
  120.     while((s[0] = c = getch()) == ' ' || c == '\t')
  121.         ;
  122.     s[1] = '\0';
  123.     if(!isdigit(c) && c != '.' && c != '-')
  124.         return c;     /* Not a number          */
  125.     i = 0;
  126.     if(c == '-'){      /* collect fraction part */
  127.         if(!isdigit(s[++i] = c = getch())) {
  128.             if(c != EOF)
  129.                 ungetch(c);
  130.             return '-';
  131.         }
  132.     }
  133.  
  134.     if(isdigit(c))    /* collect integer part  */
  135.         while(isdigit(s[++i] = c = getch()))
  136.             ;
  137.     if(c == '.')      /* collect fraction part */
  138.         while(isdigit(s[++i] = c = getch()))
  139.             ;
  140.     s[i] = '\0';
  141.     if(c != EOF)
  142.         ungetch(c);
  143.     return NUMBER;
  144. }
  145.  
  146. /* get a (possibly pushed-back) character */
  147. int getch(void)
  148. {
  149.     return (bufp > 0) ? buf[--bufp] : getchar();  
  150. }
  151.  
  152. /* push character back on input */
  153. void ungetch(int c)
  154. {
  155.     if(bufp >= BUFSIZE)
  156.         printf("ungetch: too many characters\n");
  157.     else
  158.         buf[bufp++] = c;  // Add character to buffer and increment bufp
  159. }
Advertisement
Add Comment
Please, Sign In to add comment