For this exercise, we cannot build upon the previous ones as this would break functionality that the program depends on, so we will build on from our code from exercise 4-3, which is the calculator at its most basic state while still remaining usable with support for negative numbers.
The first thing we do is replace the character array buf
with a single character. We can also get rid of bufp and
instead create the boolean variable state that can be set
to FULL
or EMPTY
to represent whether the
buffer is free. Inside ungetch
, we assign the argument
to buf only if state is not FULL
,
and then update state to FULL
. For
getch
, we normally run getchar
except for
when state is FULL
, in which case we return
buf and change state to EMPTY
.
#define MAXOP 100 /* max size of operand or operator */
#define NUMBER '0' /* signal that a number was found */
#define MAXVAL 100 /* maximum depth of val stack */
#define BUFSIZE 100
enum boolean { EMPTY, FULL };
int getop(char []);
void push(double);
double pop(void);
int getch(void);
void ungetch(int);
int sp = 0; /* next free stack position */
double val[MAXVAL]; /* value stack */
char buf[BUFSIZE]; /* buffer for ungetch */
int bufp = 0; /* next free position in buf */
char buf; /* buffer for ungetch */
int state = EMPTY; /* whether buffer is full or empty */
...
int getch(void) /* get a (possibly pushed back) character */
{
return (bufp > 0) ? buf[--bufp] : getchar();
if (state == FULL) {
state = EMPTY;
return buf;
}
return getchar();
}
void ungetch(int c) /* push character back on input */
{
if (bufp >= BUFSIZE)
printf("ungetch: too many characters\n");
else
buf[bufp++] = c;
if (state == FULL)
printf("ungetch: buffer is full\n");
else {
buf = c;
state = FULL;
}
}