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;
}