ch6-words (C keywords)

Chapter_6     Functions Exercise_6-1







Note:  We considered include and define to be C keywords, so we added them to keytab[].




words.c     K&R, p. 132-136         download


#include <stdio.h> // for getchar(), putchar(), printf(), EOF
#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);
int binsearch(char *, struct key *, int);

// count C keywords
int main()
{
int c, n;
char word[MAXWORD];

while((c = getword(word, MAXWORD)) != EOF)
{
if (isalpha(c) || c == '_')
{
if ((n = binsearch(word, keytab, NKEYS)) >= 0)
{keytab[n].count++;}
}
}

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

return 0;
}

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

low = 0;
high = n-1;

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

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

return -1; // 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 words.c -o words
./words < words.c
(2, auto), (3, break), (2, case), (9, char), (2, const),
(2, continue), (2, default), (5, define), (2, do), (2, double),
(4, else), (2, enum), (2, extern), (2, float), (9, for),
(2, goto), (13, if), (5, include), (22, int), (2, long),
(2, register), (9, return), (2, short), (2, signed), (6, sizeof),
(2, static), (6, struct), (2, switch), (2, typedef), (2, union),
(2, unsigned), (6, void), (2, volatile), (5, while),
*/









Chapter_6     Functions BACK_TO_TOP Exercise_6-1



Comments

Popular posts from this blog

Contents

Blogger Page Margins in Contempo