simple calculator / reverse Polish notation
Everything works on this calculator except handling standard subraction '-'.
For example:
(4+5)*(3/7) is written as 4 5+ 3 7/*, and the program answers correctly. It also works for negative numbers: -4 -9+ or -34 273*. However, normal subtraction requires a double '-' to work. Like this: 4 9--. If you use just a single - like this: 4 9-, it just reprints the last character (9). The problem seems to be in calling the getch() and ungetch() functions in 'getop()' but I cannot pinpoint it....
(ps. if you see the problem please also explain the concept I am missing here)
Allan
Code:
#include <stdio.h>
#include <stdlib.h>
#define MAXOP 100
#define NUMBER '0'
int getop(char []);
void push(double);
double pop(void);
void swap(double);
void clear(double);
main () { /*reverse-Polish-notation calculator*/
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((int)pop()%(int)op2);
else
printf("error: zero divisor\n");
break;
case '/':
op2=pop();
if (op2 != 0.0)
push(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;
}
#define MAXVAL 100 /*maximum depth of val stack*/
int sp=0; /*next free stack position*/
double val[MAXVAL]; /*value stack*/
/*push:push f onto value stack*/
void push(double f)
{
if (sp<MAXVAL)
val[sp++]=f;
else
printf("error: stack full, can't push %g\n", f);
}
/*pop: pop and return top value from stack*/
double pop(void)
{
if (sp>0)
return val[--sp];
else {
printf("error: stack empty\n");
return 0.0;
}
}
#include <ctype.h>
int getch(void);
void ungetch(int);
/*getop: get next character or numeric operand*/
int getop(char s[])
{
int i,c;
while ((s[0]=c=getch())==' ' || c == '\t')
;
s[1]='\0';
i=0;
if(!isdigit(c)&&c!='.')
if (c=='-' && (isdigit(s[++i]=c=getch()))) /*have to use '2 3--' (double -) to get subtraction...*/
;
else
return c; /*not a number*/
if (isdigit(c)) /*collect integer part*/
while (isdigit(s[++i]=c=getch()));
;
if (c=='.') /*collect fraction part*/
while (isdigit(s[++i]=c=getch()))
;
s[i]='\0';
if (c!=EOF)
ungetch(c);
return NUMBER;
}
#define BUFSIZE 100
char buf[BUFSIZE]; /*buffer for ungetch*/
int bufp=0; /*next free position in buf*/
int getch(void) /*get a (possibly pushed-back) character */
{
return (bufp>0) ? buf[--bufp] : getchar();
}
void ungetch(int c)
{
if (bufp>=BUFSIZE)
printf("ungetch:too many characters\n");
else
buf[bufp++]=c;
}