lolamontes69

K+R Exercise6_1

Sep 25th, 2014
227
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 4.01 KB | None | 0 0
  1. /* Our version of getword does not properly handle underscores, string constants,
  2.  * comments, or preprocessor control lines. Write a better version
  3.  * */
  4. #include <stdio.h>
  5. #include <ctype.h>
  6. #include <string.h>
  7.  
  8. #define MAXWORD 100
  9. #define BUFSIZE 100
  10.  
  11. struct key {
  12.     char *word;
  13.     int count;
  14. } keytab[] = {
  15.     "#define",0,
  16.     "#elif",0,
  17.     "#else",0,
  18.     "#endif",0,
  19.     "#error",0,
  20.     "#if",0,
  21.     "#ifdef",0,
  22.     "#ifndef",0,
  23.     "#include",0,
  24.     "#line",0,
  25.     "#pragma",0,
  26.     "#undef",0,
  27.     "auto",0,
  28.     "break",0,
  29.     "case",0,
  30.     "char",0,
  31.     "const",0,
  32.     "continue",0,
  33.     "default",0,
  34.     "do",0,
  35.     "double",0,
  36.     "else",0,
  37.     "enum",0,
  38.     "extern",0,
  39.     "float",0,
  40.     "for",0,
  41.     "goto",0,
  42.     "if",0,
  43.     "int",0,
  44.     "long",0,
  45.     "register",0,
  46.     "return",0,
  47.     "short",0,
  48.     "signed",0,
  49.     "sizeof",0,
  50.     "static",0,
  51.     "struct",0,
  52.     "switch",0,
  53.     "typedef",0,
  54.     "union",0,
  55.     "unsigned",0,
  56.     "void",0,
  57.     "volatile",0,
  58.     "while",0
  59. };
  60.  
  61. #define NKEYS (sizeof keytab / sizeof(keytab[0])) /* space req between NKEYS ()*/
  62. char buf[BUFSIZE];
  63. int bufp = 0;
  64.  
  65. int getword(char *, int);
  66. int binsearch(char *, struct key *, int);
  67. int escapecom(char *w);
  68.  
  69. /* count C keywords */
  70. main()
  71. {
  72.     int n;
  73.     char word[MAXWORD];
  74.  
  75.     while(getword(word,MAXWORD)!=EOF)
  76.         if(isalpha(word[0]) || word[0]=='#')
  77.             if((n=binsearch(word,keytab,NKEYS))>=0)
  78.                 keytab[n].count++;
  79.     for(n=0; n<NKEYS; n++)
  80.         if(keytab[n].count > 0)
  81.             printf("%4d %s\n",
  82.                 keytab[n].count, keytab[n].word);
  83.     return 0;
  84. }
  85.  
  86. /* binsearch: find word in tab[0]...tab[n-1] */
  87. int binsearch(char *word, struct key tab[], int n)
  88. {
  89.     int cond;
  90.     int low, high, mid;
  91.  
  92.     low  = 0;
  93.     high = n-1;
  94.     while(low <= high) {
  95.         mid = (low+high)/2;
  96.         if((cond=strcmp(word,tab[mid].word)) < 0)  /* do a binary search amongst keywords */
  97.             high = mid-1;                          /* to see if word is amongst them      */
  98.         else if(cond>0)                            /* if so it returns its index          */
  99.             low=mid+1;
  100.         else
  101.             return mid;
  102.     }
  103.     return -1;
  104. }
  105.  
  106. /* getword: get nextword or character from input */
  107. int getword(char *word, int lim)
  108. {
  109.     int c, getch(void);
  110.     void ungetch(int);
  111.     char *w = word;
  112.  
  113.     while(isspace(c=getch()))
  114.         ;
  115.     if(c!=EOF)
  116.         *w++ = c;
  117.     if(!isalpha(c) && c!='"' && c!='\'' && c!='_' && c!='/' && c!='#') {
  118.         *w = '\0';
  119.         return c;
  120.     }
  121.     if(c=='#') {
  122.         while((c=getch())==' ') /* skip any spaces between '#' and keyword */
  123.             ;
  124.         *w++=c;
  125.     }
  126.     if(c=='"')
  127.         while((c=getch()) != '"' && c!='\n' && c!=EOF)
  128.             ;
  129.     else if(c=='\'')
  130.         while((c=getch()) != '\'' && c!='\n' && c!=EOF)
  131.             ;
  132.     else if(c=='/') escapecom(w);
  133.     for( ; --lim > 0; w++)
  134.         if(!isalnum(*w=getch()) && *w!='_') {
  135.                                       /* This adds to word and breaks on non-alnum*/
  136.             ungetch(*w);              /* so continue with underscores */
  137.             break;
  138.         }
  139.     *w = '\0';
  140.     return word[0];
  141. }
  142.  
  143. /* get a (possibly pushed-back) character */
  144. int getch(void)
  145. {
  146.     return (bufp > 0) ? buf[--bufp] : getchar();
  147. }
  148.  
  149. /* push character back on input */
  150. void ungetch(int c)
  151. {
  152.     if(bufp >= BUFSIZE)
  153.         printf("ungetch: too many characters\n");
  154.     else
  155.         buf[bufp++] = c;
  156. }
  157.  
  158. /* escapecom: see if a comment if so escape commented data */
  159. int escapecom(char *w)
  160. {
  161.     char c;
  162.    
  163.     c = getch();
  164.     if(c!='*') {
  165.         *w--;
  166.         while(c==' ')
  167.             c=getch(); /* skip spaces then */
  168.         *w++=c;        /* add char to word */
  169.         return 0;
  170.     }
  171.     while(1) {
  172.         while((c=getch())!='*' && c!=EOF) /* skip chars until valid end of comment */
  173.             ;
  174.         if((c=getch())=='/' || c==EOF)
  175.             return 0;
  176.     }
  177. }
Advertisement
Add Comment
Please, Sign In to add comment