Similar to before, we will use the code from exercise 4-3 as a starting point as implementing this in our more recent programs would break functionality.
In order to rewrite getop without having the ability to
push back a character, we change c to be
static, which means its value carries over the next time
getop is called. At the start of getop,
instead of always reading in at least one new character, we only read
in characters as long as c is a whitespace character.
c will be initialized to a whitespace character so that on
the first run, the next character is read. Doing this instead means we
no longer need to push back c as it will carry over by
default. In cases where we would normally not execute
ungetch, we simply set c to whitespace so that
the next character will be read into c the next time
getop is called. Note that as c is actually
equal the character that will carry over, wherever we returned
c before, we now need to return s[0] instead
(which prior to this change was equivalent to c.)
/* getop: get next operator or numeric operand */
int getop(char s[])
{
int i, c;
int i;
static int c = ' ';
while ((s[0] = c = getch()) == ' ' || c == '\t')
;
while (c == ' ' || c == '\t')
s[0] = c = getchar();
s[1] = '\0';
if (!isdigit(c) && c != '.' && c != '+' && c != '-') {
c = ' '; /* read next character next time getop is run */
return c; /* not a number */
return s[0]; /* not a number */
}
i = 0;
if (isdigit(c) || c == '+' || c == '-') /* collect integer part */
while (isdigit(s[++i] = c = getchar()))
;
if (c == '.') /* collect fraction part */
while (isdigit(s[++i] = c = getchar()))
;
if (c != EOF)
ungetch(c);
s[i] = '\0';
if ((s[0] == '+' || s[0] == '-') && i == 1)
return s[0]; /* return operator if no digits afterwards */
return NUMBER;
}