ch6-wordp (C keywords, pointer version)

Chapter_6     Exercise_6-1 tree     Exercise_6-2







Note:  The pointer variant wordp still works with nocomment from Exercise_6-1 (see also ch6-words).




wordp.c     K&R, p. 133, 136-137         download


#include <stdio.h> // for getchar(), putchar(), printf(), EOF, NULL
#include <string.h> // for strcmp()
#include <ctype.h> // for isspace(), isalpha(), isalnum()

#define MAXWORD 100
// #define NKEYS (sizeof (keytab) / sizeof(struct key))
#define NKEYS (sizeof (keytab) / sizeof(keytab[0]))

struct key
{
char *word;
int count;
} keytab[] =
{{"auto", 0}, {"break", 0}, {"case", 0}, {"char", 0}, {"const", 0}, {"continue", 0},
{"default", 0}, {"define", 0}, {"do", 0}, {"double", 0}, {"else", 0}, {"enum", 0},
{"extern", 0}, {"float", 0}, {"for", 0}, {"goto", 0}, {"if", 0}, {"include", 0},
{"int", 0}, {"long", 0}, {"register", 0}, {"return", 0}, {"short", 0}, {"signed", 0},
{"sizeof", 0}, {"static", 0}, {"struct", 0}, {"switch", 0}, {"typedef", 0},
{"union", 0}, {"unsigned", 0}, {"void", 0}, {"volatile", 0}, {"while", 0}};

int getword(char *, int);

struct key * // function binsearch() returns pointer to struct key
binsearch(char *, struct key *, int);

// count C keywords, pointer version
int main()
{
int c;
char word[MAXWORD];
struct key *p;

while((c = getword(word, MAXWORD)) != EOF)
{
if (isalpha(c) || c == '_')
{
if ((p = binsearch(word, keytab, NKEYS)) != NULL)
{p->count++;}
}
}

for (p = keytab, c = 0; p < keytab + NKEYS; p++)
{
if (p->count > 0)
{
c++;
printf("(%d, %s), ", p->count, p->word);
if (c % 5 == 0) {putchar('\n');}
}
}
if (c % 5 != 0) {putchar('\n');}

return 0;
}

struct key * // function binsearch() returns pointer to struct key
binsearch(char *word, struct key *tab, int n)
{// find word in tab[0] ... tab[n-1]
int cond;
struct key *low, *high, *mid;

low = tab; // &tab[0]
high = tab+n-1; // &tab[n-1]

while (low <= high)
{
mid = low + (high - low) / 2; // pointer arithmetic

if ((cond = strcmp(word, mid->word)) < 0)
{high = mid-1;}
else if (cond > 0)
{low = mid + 1;}
else {return mid;} // found it
}

return NULL; // not found
}

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

// get next word or character from input
int getword(char *word, int lim)
{
int c;
char *w = word;

while (isspace(c = getch()))
{} // skip beginning whitespace

if (c != EOF)
{*w++ = c;}

if (!isalpha(c) && c != '_')
{
*w = '\0';
return c;
}

for ( ; --lim > 0; w++)
{
if (!isalnum(*w = getch()) && *w != '_')
{
ungetch(*w);
break; // out of for(), w++ is not executed
}
}

*w = '\0';
return word[0];
}

// buffer for ungetch():
int buf = EOF-1; // not a real character, not even EOF

int getch(void) // get a (possibly pushed-back) character
{
if (buf < EOF)
{
return getchar();
}

int temp = buf; // buf >= EOF
buf = EOF-1; // reset buf

return temp;
}
// push character back on input (make it available for the next getch()):
void ungetch(int c)
{
buf = c;
}
/*
gcc wordp.c -o wordp
./wordp < wordp.c
(2, auto), (5, break), (2, case), (10, char), (2, const),
(2, continue), (2, default), (7, define), (2, do), (2, double),
(6, else), (2, enum), (2, extern), (2, float), (10, for),
(2, goto), (15, if), (7, include), (21, int), (2, long),
(2, register), (11, return), (2, short), (2, signed), (7, sizeof),
(2, static), (13, struct), (2, switch), (2, typedef), (2, union),
(2, unsigned), (7, void), (2, volatile), (7, while),

./nocomment < nocomment.c > copy.c
./wordp < copy.c
(2, break), (2, define), (9, else), (20, if), (1, include),
(3, int), (10, return), (6, while),

./nocomment < wordp.c > copy.c
./wordp < copy.c
(1, break), (7, char), (2, define), (2, else), (2, for),
(11, if), (3, include), (17, int), (7, return), (2, sizeof),
(7, struct), (4, void), (3, while),

rm copy.c // clean
*/









Chapter_6     Exercise_6-1 BACK_TO_TOP tree     Exercise_6-2



Comments

Popular posts from this blog

Contents

Blogger Page Margins in Contempo