1 #include<stdio.h>
2 #include<ctype.h>
3 #include<string.h>
4
5 //#define DEBUG
6 #ifdef DEBUG
7 #define p(x) printf("%d\n",x)
8 #else
9 #define p(x)
10 #endif
11
12 #define MAXWORD 16 /*单词的的长度*/
13 #define NKEYS (sizeof keytab /sizeof(struct key))
14
15 #define BUFSIZE 100
16 char buf[BUFSIZE]; /*用于ungetch 函数的缓冲区*/
17 int bufp = 0; /*buf 中下一个空闲位置*/
18
19 int getword(char *, int);
20 struct key *binsearch(char *, struct key *, int);
21 int getch(void); /*取一个字符(可能是压回的字符)*/
22 void ungetch(int c);
23
24 struct key{
25 char *word;
26 int count;
27 }keytab[] = {
28 "auto" , 0,
29 "break", 0,
30 "case" , 0,
31 "char" , 0,
32 "const", 0,
33 "continue", 0,
34 "default" , 0,
35 "unsigned", 0,
36 "void" , 0,
37 "volatile", 0,
38 "while" , 0
39 };
40
41 /*count C keywords; pointer version*/
42 int main(void)
43 {
44 char word[MAXWORD];
45 struct key *p;
46 //p(NKEYS);
47
48 /*查找*/
49 while(getword(word, MAXWORD) != EOF )
50 if(isalpha(word[0]))
51 if((p = binsearch(word, keytab, NKEYS)) != NULL)
52 p->count++;
53
54 p(p->count);
55 /*打印*/
56 for(p = keytab; p < keytab + NKEYS; p++){
57 if(p->count > 0);
58 printf("%4d %s\n", p->count, p->word);
59 }
60 return 0;
61 }
62
63 /*binsearch: find word in tab[0] ... tab[n-1]*/
64 struct key *binsearch(char *word, struct key *tab, int n)
65 {
66 int cond;
67
68 struct key *low = &tab[0];
69 struct key *high = &tab[n];
70 struct key *mid;
71
72 while(low < high){
73 mid = low + (high - low) / 2;
74 if((cond = strcmp(word, mid->word)) < 0)
75 high = mid;
76 else if(cond > 0)
77 low = mid + 1;
78 else
79 return mid;
80 }
81 return NULL;
82 }
83
84 /*getword: get next word or character from input*/
85 int getword(char * word, int lim)
86 {
87 int c, getch(void);
88 void ungetch(int);
89 char *w = word;
90
91 while(isspace(c = getch()))/*跳过开始的空格*/
92 ;
93 if(c != EOF)
94 *w++ = c;
95 if(!isalpha(c)){
96 *w = '\0';
97 return c;
98 }
99
100 for(; --lim > 0; w++) /*--lim 把前面的一个字符 也算进来 就先-- 再判断*/
101 if(!isalnum(*w = getch())){ /*当读入的字符不属于字母数字集合时 说明多读入了一个字符 调用ungetch 将多读入的一个字符放回到输入中*/
102 ungetch(*w);
103 break;
104 }
105 *w = '\0';
106 //p(1);
107 return word[0];
108 }
109
110 /**/
111 int getch(void)/*取一个字符(可能是压回的字符bufp > 0 表明有压回字符 --bufp为压回字符)*/
112 {
113 return (bufp > 0) ? buf[--bufp] : getchar();
114 }
115 void ungetch(int c)
116 {
117 if(bufp >= BUFSIZE)
118 printf("ungetch: too many characters\n");
119 else
120 buf[bufp++] = c;
121 }
参考:《c程序设计语言》 第2版