3

The buf array will never have more than one element, because of getop's implementation. So, couldn't it be declared as an ordinary char variable?

This is the source code of the program, pages 74 - 79:

#include <ctype.h>

int getch(void);
void ungetch(int);

/* getop: get next character or numeric operand */
int getop(char s[]) /* we pass s[] to getop to store input */
{
    int i, c;

    while ((s[0] = c = getch()) == ' ' || c == '\t')
        ;
    s[1] = '\0';
    if (!isdigit(c) && c != '.')
        return c; /* not a number */
    i = 0;
    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;
/* getch: the function which actually gets chars! */
int getch(void) /* get a (possibly pushed-back) character */
{
    return (bufp > 0) ? buf[--bufp] : getchar();
}

void ungetch(int c) /* push character back in input */
{
    if (bufp >= BUFSIZE)
        printf("ungetch: too many characters\n");
    else
        buf[bufp++] = c;
}
Deduplicator
  • 44,692
  • 7
  • 66
  • 118
cristid9
  • 1,070
  • 1
  • 17
  • 37
  • 1
    There's a bit of code missing in your excerpt. The statement `while ((s[0] = c = getch())` in `getop` would imply that `buf` may hold more than one character. That can't be determined from the limited code sample shown. If it were true that only one character were ever put into `buf`, then, sure, you would only need one `char`. But I suspect you're misinterpreting the rest of the code. – lurker Jan 03 '14 at 16:33
  • ungetchar() is used only once in getop, so it could upload to buffer only one char per fucntion call. – cristid9 Jan 03 '14 at 16:38
  • That's just `ungetchar` which is used in specific cases. The buffer uld be loaded from other places as well, not shown in any of the code you have displayed. I doubt `uncgetch` is the mechanism by which the buffer is generally loaded. It's more of a utility function to "undo" a prior `getch`. You need to look at all of the code on pages 74-79 and see where `buf` is used. – lurker Jan 03 '14 at 16:42
  • Here is the full source code: http://pastebin.com/jXGp0aKx, it seems that buf is only used inside getch and ungetch. – cristid9 Jan 03 '14 at 16:52
  • Thanks. `ungetch` is called near the end of `getop`. Is it possible it could be called multiple times before `getch` is called? – lurker Jan 03 '14 at 17:48
  • No, because ungetch pushes back only characters read by getch that are not ok or should be evaluated later. – cristid9 Jan 03 '14 at 19:28
  • Yes, after staring at this further, it does seem unnecessary to have a buffer longer than one character. It may be there for the purpose of future flexibility. Or, it was started that way with a thought in mind for implementation which did not occur. Or just to make the reader go crazy trying to figure out why it's there. ;) – lurker Jan 03 '14 at 19:34

2 Answers2

4

A few paragraphs after the discussion of getop(), the book has this to say about the ungetch() implementation (emphasis added):

The standard library includes a function ungetch that provides one character of pushback; we will discuss it in Chapter 7. We have used an array for the pushback, rather than a single character, to illustrate a more general approach.

Michael Burr
  • 333,147
  • 50
  • 533
  • 760
0

BUFSIZE could be 1 if getop() is the only function to call ungetch().

Based on this post, the higher level code may have called ungetch() multiple times before calling getop(), thus filling more than 1 char into buf.

chux - Reinstate Monica
  • 143,097
  • 13
  • 135
  • 256