Doing an assignment to create a struct that holds keywords and then is used with a binary search to counter the total keywords in a program. Below is my code and below it is the errors i get when I attempt to compile it. First question is what is wrong with my struct setup that is causing the division by 0 error.

#include <stdio.h>
#define MAXWORD 20
#define LETTER 'a'
#define DIGIT '0'
#define NKEYS (sizeof (keytab)/ sizeof (struct key))
                /*whole bytes      bytes in element*/
struct keytab
  {
   char *keyword;
   int keycount;
  }

   keytab[NKEYS]={
          "auto", 0,
          "break", 0,
          "case",0,
          "char", 0,
          "const", 0,
          "continue", 0,
          "default", 0,
          "do", 0,
          "double", 0,
          "else", 0,
          "enum", 0,
          "extern", 0,
          "float", 0,
          "for", 0,
          "goto", 0,
          "if", 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 binsearch(char word,struct key tab,int n);
int getword(char w,int lim);

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

  while ((t = getword(word, MAXWORD)) !=EOF)
    if (t== LETTER)
        if (n = binsearch(word, keytab, NKEYS)) >=0)
          keytab[n].keycount++;

  for (n=0; n < NKEYS; n++)
     if (keytab[n].keycount >0)
        printf("%4d %s\n", keytab[n].keycount, keytab[n].keyword);
}

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

  low=0;
  high = n-1;
  while (low <= high)
    {
        mid = (low+high)/2;
        if (( cond =strcmp(word, tab[mid].keyword)) < 0)
           high = mid -1;

        else if (cond >0)
           low = mid +1;

        else
           return(mid);
   }
return (-1)
}

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

  if (type(c = *w++ = getch()) != LETTER)
   {
    *w = '\0';
    return(c);
   }

   while (-- lim > 0)
        {
        t = type (c = *w++ = getch());
        if (t != LETTER && t != DIGIT)
          {
           ungetch(c);
           break;
          }
        }
  *(w-1) = '\0';
  return(LETTER);
}
type(c)  /* return type of ASCII character */
int c;
{
  if (c >= 'a' && c <= 'z' || c >= 'A' && c <= 'Z')
     return(LETTER);
  else if (c >= '0' && c <= '9')
     return(DIGIT);
  else
     return(c);
}

"keyword.c", line 13: undefined symbol: keytab
"keyword.c", line 13: incomplete struct/union/enum key: sizeof()
"keyword.c", line 13: division by 0
"keyword.c", line 13: zero or negative subscript
"keyword.c", line 14: too many array initializers
"keyword.c", line 56: warning: improper pointer/integer combination: arg #1
"keyword.c", line 58: warning: improper pointer/integer combination: arg #1
"keyword.c", line 58: argument #2 is incompatible with prototype:
prototype: struct key {} : "keyword.c", line 48
argument : int
"keyword.c", line 58: warning: division by 0
"keyword.c", line 58: syntax error before or at: >=
"keyword.c", line 61: warning: division by 0
"keyword.c", line 62: cannot dereference non-pointer type
"keyword.c", line 62: warning: left operand of "." must be struct/union object
"keyword.c", line 62: cannot access member of non-struct/union object
"keyword.c", line 63: cannot dereference non-pointer type
"keyword.c", line 63: warning: left operand of "." must be struct/union object
"keyword.c", line 63: cannot access member of non-struct/union object
"keyword.c", line 63: cannot dereference non-pointer type
"keyword.c", line 63: warning: left operand of "." must be struct/union object
"keyword.c", line 64: cannot recover from previous errors
cc: acomp failed for keyword.c

Recommended Answers

All 19 Replies

Add a ; after your keytab structure.

On line 13 you don't have a type name (like int keytab[] )

I corrected the ; error but I am not sure why I would need to make a type for keytab when I define it as a structure in the lines before the error message? If I do have to declare a type for keytab should I use int?

Line 13. Is keytab a TYPE or is keytab the name of a variable? You seem to want to use it as both. I imagine you want something like this:

keytab keytabs[NKEYS] = {/* initialization */};

ok its seems i used the struct method incorrectly. I am wondering if I should have done struct key { statement}; the key keytab[NKEYS]= initialization;

OK, I change the struct keytab to key and then placed key keytab[NKEYS] = {initialization}; and I got these errors.

"keyword.c", line 13: warning: old-style declaration or incorrect type for: key
"keyword.c", line 13: syntax error before or at: keytab
"keyword.c", line 13: undefined symbol: keytab
"keyword.c", line 13: zero or negative subscript
"keyword.c", line 13: warning: old-style declaration or incorrect type for: keytab
"keyword.c", line 14: too many array initializers
"keyword.c", line 56: warning: improper pointer/integer combination: arg #1
"keyword.c", line 58: warning: improper pointer/integer combination: arg #1
"keyword.c", line 58: argument #2 is incompatible with prototype:
prototype: struct key {pointer to char keyword, int keycount} : "keyword.c", line 48
argument : int
"keyword.c", line 58: syntax error before or at: >=
"keyword.c", line 62: cannot dereference non-pointer type
"keyword.c", line 62: warning: left operand of "." must be struct/union object
"keyword.c", line 62: cannot access member of non-struct/union object
"keyword.c", line 63: cannot dereference non-pointer type
"keyword.c", line 63: warning: left operand of "." must be struct/union object
"keyword.c", line 63: cannot access member of non-struct/union object
"keyword.c", line 63: cannot dereference non-pointer type
"keyword.c", line 63: warning: left operand of "." must be struct/union object
"keyword.c", line 64: cannot recover from previous errors

#include <stdio.h>
#define MAXWORD 20
#define LETTER 'a'
#define DIGIT '0'
#define NKEYS (sizeof (keytab) / sizeof (struct key))
                /*whole bytes      bytes in element*/
struct key
  {
   char *keyword;
   int keycount;
  };

key keytab[NKEYS]={
          "auto", 0,
          "break", 0,
          "case",0,
          "char", 0,
          "const", 0,
          "continue", 0,
          "default", 0,
          "do", 0,
          "double", 0,
          "else", 0,
          "enum", 0,
          "extern", 0,
          "float", 0,
          "for", 0,
          "goto", 0,
          "if", 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 binsearch(char word,struct key tab,int n);
int getword(char w,int lim);

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

  while ((t = getword(word, MAXWORD)) !=EOF)
    if (t== LETTER)
        if (n = binsearch(word, keytab, NKEYS)) >=0)
          keytab[n].keycount++;

  for (n=0; n < NKEYS; n++)
     if (keytab[n].keycount >0)
        printf("%4d %s\n", keytab[n].keycount, keytab[n].keyword);
}

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

  low=0;
  high = n-1;
  while (low <= high)
    {
        mid = (low+high)/2;
        if (( cond =strcmp(word, tab[mid].keyword)) < 0)
           high = mid -1;

        else if (cond >0)
           low = mid +1;

        else
           return(mid);
   }
return (-1)
}

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

  if (type(c = *w++ = getch()) != LETTER)
   {
    *w = '\0';
    return(c);
   }

   while (-- lim > 0)
        {
        t = type (c = *w++ = getch());
        if (t != LETTER && t != DIGIT)
          {
           ungetch(c);
           break;
          }
        }
  *(w-1) = '\0';
  return(LETTER);
}
type(c)  /* return type of ASCII character */
int c;
{
  if (c >= 'a' && c <= 'z' || c >= 'A' && c <= 'Z')
     return(LETTER);
  else if (c >= '0' && c <= '9')
     return(DIGIT);
  else
     return(c);
}

ok its seems i used the struct method incorrectly. I am wondering if I should have done struct key { statement}; the key keytab[NKEYS]= initialization;

Name them whatever you want. Just make sure the variable name is different from the struct's name and that the code below it matches the variable name.

I did that and then got the errors listed in the response above

Try this on your initialization. You're missing some brackets.

key keytab[NKEYS]=
{
   {"auto", 0},
   {"break", 0},
   /* etc */
   {"while", 0}
};

the brackets didn't matter still had the same errors.

>> the brackets didn't matter still had the same errors.

They matter. There's just an error on line 5 that confuses the compiler so that doesn't fix it. Move line 5 down to line 47. Replace [NKEYS] on line 13 with just the brackets []. It'll figure out the size on its own.

ok moved NKEYS down to line 47 and removed NKEYS from inside the array and not have this error printout.

"keyword.c", line 11: warning: old-style declaration or incorrect type for: key
"keyword.c", line 11: syntax error before or at: keytab
"keyword.c", line 11: warning: old-style declaration or incorrect type for: keytab
"keyword.c", line 12: warning: improper pointer/integer combination: op "="
"keyword.c", line 12: too many initializers for scalar
"keyword.c", line 13: syntax error before or at: {
"keyword.c", line 44: warning: syntax error:  empty declaration
"keyword.c", line 56: warning: improper pointer/integer combination: arg #1
"keyword.c", line 58: warning: improper pointer/integer combination: arg #1
"keyword.c", line 58: argument #2 is incompatible with prototype:
        prototype: struct key {pointer to char keyword, int keycount} : "keyword.c", line 48
        argument : pointer to int
"keyword.c", line 58: syntax error before or at: >=
"keyword.c", line 62: warning: left operand of "." must be struct/union object
"keyword.c", line 62: cannot access member of non-struct/union object
"keyword.c", line 63: warning: left operand of "." must be struct/union object
"keyword.c", line 63: cannot access member of non-struct/union object
"keyword.c", line 63: warning: left operand of "." must be struct/union object
"keyword.c", line 64: cannot recover from previous errors

I don't get any errors before main. You'll have to post the revised code.

#include <stdio.h>
#define MAXWORD 20
#define LETTER 'a'
#define DIGIT '0'
struct key
  {
   char *keyword;
   int keycount;
  };

key keytab[]={
         {"auto", 0,}
         {"break", 0,}
         {"case",0,}
         {"char", 0,}
         {"const", 0,}
         {"continue", 0,}
         {"default", 0,}
         {"do", 0,}
         {"double", 0,}
         {"else", 0,}
         {"enum", 0,}
         {"extern", 0,}
         {"float", 0,}
         {"for", 0,}
         {"goto", 0,}
         {"if", 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,}
          };
#define NKEYS (sizeof (keytab) / sizeof (struct key))
                /*whole bytes      bytes in element*/

int binsearch(char word,struct key tab,int n);
int getword(char w,int lim);

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

  while ((t = getword(word, MAXWORD)) !=EOF)
    if (t== LETTER)
        if (n = binsearch(word, keytab, NKEYS)) >=0)
          keytab[n].keycount++;

  for (n=0; n < NKEYS; n++)
     if (keytab[n].keycount >0)
        printf("%4d %s\n", keytab[n].keycount, keytab[n].keyword);
}

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

  low=0;
  high = n-1;
  while (low <= high)
    {
        mid = (low+high)/2;
        if (( cond =strcmp(word, tab[mid].keyword)) < 0)
           high = mid -1;

        else if (cond >0)
           low = mid +1;

        else
           return(mid);
   }
return (-1)
}

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

  if (type(c = *w++ = getch()) != LETTER)
   {
    *w = '\0';
    return(c);
   }

   while (-- lim > 0)
        {
        t = type (c = *w++ = getch());
        if (t != LETTER && t != DIGIT)
          {
           ungetch(c);
           break;
          }
        }
  *(w-1) = '\0';
  return(LETTER);
}
type(c)  /* return type of ASCII character */
int c;
{
  if (c >= 'a' && c <= 'z' || c >= 'A' && c <= 'Z')
     return(LETTER);
  else if (c >= '0' && c <= '9')
     return(DIGIT);
  else
     return(c);
}
{"auto", 0,}

Second comma goes AFTER the brackets. See my earlier post.

{"auto", 0},
#include <stdio.h>
#define MAXWORD 20
#define LETTER 'a'
#define DIGIT '0'
struct key
  {
   char *keyword;
   int keycount;
  };

key keytab[]={
         {"auto", 0},
         {"break", 0},
         {"case",0},
         {"char", 0},
         {"const", 0},
         {"continue", 0},
         {"default", 0},
         {"do", 0},
         {"double", 0},
         {"else", 0},
         {"enum", 0},
         {"extern", 0},
         {"float", 0},
         {"for", 0},
         {"goto", 0},
         {"if", 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},
          };
#define NKEYS (sizeof (keytab) / sizeof (struct key))
                /*whole bytes      bytes in element*/

int binsearch(char word,struct key tab,int n);
int getword(char w,int lim);

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

  while ((t = getword(word, MAXWORD)) !=EOF)
    if (t== LETTER)
        if (n = binsearch(word, keytab, NKEYS)) >=0)
          keytab[n].keycount++;

  for (n=0; n < NKEYS; n++)
     if (keytab[n].keycount >0)
        printf("%4d %s\n", keytab[n].keycount, keytab[n].keyword);
}

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

  low=0;
  high = n-1;
  while (low <= high)
    {
        mid = (low+high)/2;
        if (( cond =strcmp(word, tab[mid].keyword)) < 0)
           high = mid -1;

        else if (cond >0)
           low = mid +1;

        else
           return(mid);
   }
return (-1)
}

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

  if (type(c = *w++ = getch()) != LETTER)
   {
    *w = '\0';
    return(c);
   }

   while (-- lim > 0)
        {
        t = type (c = *w++ = getch());
        if (t != LETTER && t != DIGIT)
          {
           ungetch(c);
           break;
          }
        }
  *(w-1) = '\0';
  return(LETTER);
}
type(c)  /* return type of ASCII character */
int c;
{
  if (c >= 'a' && c <= 'z' || c >= 'A' && c <= 'Z')
     return(LETTER);
  else if (c >= '0' && c <= '9')
     return(DIGIT);
  else
     return(c);
}

"keyword.c", line 11: warning: old-style declaration or incorrect type for: key
"keyword.c", line 11: syntax error before or at: keytab
"keyword.c", line 11: warning: old-style declaration or incorrect type for: keytab
"keyword.c", line 12: warning: improper pointer/integer combination: op "="
"keyword.c", line 12: too many initializers for scalar
"keyword.c", line 13: warning: improper pointer/integer combination: op "="
"keyword.c", line 13: too many initializers for scalar
"keyword.c", line 14: warning: improper pointer/integer combination: op "="
"keyword.c", line 14: too many initializers for scalar
"keyword.c", line 15: warning: improper pointer/integer combination: op "="
"keyword.c", line 15: too many initializers for scalar
"keyword.c", line 16: warning: improper pointer/integer combination: op "="
"keyword.c", line 16: too many initializers for scalar
"keyword.c", line 17: warning: improper pointer/integer combination: op "="
"keyword.c", line 17: too many initializers for scalar
"keyword.c", line 18: warning: improper pointer/integer combination: op "="
"keyword.c", line 18: too many initializers for scalar
"keyword.c", line 19: warning: improper pointer/integer combination: op "="
"keyword.c", line 19: too many initializers for scalar
"keyword.c", line 20: warning: improper pointer/integer combination: op "="
"keyword.c", line 20: too many initializers for scalar
"keyword.c", line 21: warning: improper pointer/integer combination: op "="
"keyword.c", line 21: too many initializers for scalar
"keyword.c", line 22: warning: improper pointer/integer combination: op "="
"keyword.c", line 22: too many initializers for scalar
"keyword.c", line 23: warning: improper pointer/integer combination: op "="
"keyword.c", line 23: too many initializers for scalar
"keyword.c", line 24: warning: improper pointer/integer combination: op "="
"keyword.c", line 24: too many initializers for scalar
"keyword.c", line 25: warning: improper pointer/integer combination: op "="
"keyword.c", line 25: too many initializers for scalar
"keyword.c", line 26: warning: improper pointer/integer combination: op "="
"keyword.c", line 26: too many initializers for scalar
"keyword.c", line 27: warning: improper pointer/integer combination: op "="
"keyword.c", line 27: too many initializers for scalar
"keyword.c", line 28: warning: improper pointer/integer combination: op "="
"keyword.c", line 28: too many initializers for scalar
"keyword.c", line 29: warning: improper pointer/integer combination: op "="
"keyword.c", line 29: too many initializers for scalar
"keyword.c", line 30: warning: improper pointer/integer combination: op "="
"keyword.c", line 30: too many initializers for scalar
"keyword.c", line 31: warning: improper pointer/integer combination: op "="
"keyword.c", line 31: too many initializers for scalar
"keyword.c", line 32: warning: improper pointer/integer combination: op "="
"keyword.c", line 32: too many initializers for scalar
"keyword.c", line 33: warning: improper pointer/integer combination: op "="
"keyword.c", line 33: too many initializers for scalar
"keyword.c", line 34: warning: improper pointer/integer combination: op "="
"keyword.c", line 34: too many initializers for scalar
"keyword.c", line 35: warning: improper pointer/integer combination: op "="
"keyword.c", line 35: too many initializers for scalar
"keyword.c", line 36: warning: improper pointer/integer combination: op "="
"keyword.c", line 36: too many initializers for scalar
"keyword.c", line 37: warning: improper pointer/integer combination: op "="
"keyword.c", line 37: too many initializers for scalar
"keyword.c", line 38: warning: improper pointer/integer combination: op "="
"keyword.c", line 38: too many initializers for scalar
"keyword.c", line 39: warning: improper pointer/integer combination: op "="
"keyword.c", line 39: too many initializers for scalar
"keyword.c", line 40: warning: improper pointer/integer combination: op "="
"keyword.c", line 40: too many initializers for scalar
"keyword.c", line 41: warning: improper pointer/integer combination: op "="
"keyword.c", line 41: too many initializers for scalar
"keyword.c", line 42: warning: improper pointer/integer combination: op "="
"keyword.c", line 42: too many initializers for scalar
"keyword.c", line 43: warning: improper pointer/integer combination: op "="
"keyword.c", line 43: too many initializers for scalar
"keyword.c", line 56: warning: improper pointer/integer combination: arg #1
"keyword.c", line 58: warning: improper pointer/integer combination: arg #1
"keyword.c", line 58: argument #2 is incompatible with prototype:
prototype: struct key {pointer to char keyword, int keycount} : "keyword.c", line 48
argument : pointer to int
"keyword.c", line 58: syntax error before or at: >=
"keyword.c", line 62: warning: left operand of "." must be struct/union object
"keyword.c", line 62: cannot access member of non-struct/union object
"keyword.c", line 63: warning: left operand of "." must be struct/union object
"keyword.c", line 63: cannot access member of non-struct/union object
"keyword.c", line 63: warning: left operand of "." must be struct/union object
"keyword.c", line 64: cannot recover from previous errors
new error statement

keyword.c

Just noticed this. This is the C++ forum, not the C forum. You're in the wrong forum.

You can't leave off the keyword "struct" in C like you can in C++.

struct key keytab[]={/* etc */

corrected the struct but still getting errors
not sure where the syntax error is on line 58?

#include <stdio.h>
#define MAXWORD 20
#define LETTER 'a'
#define DIGIT '0'
#define NKEYS (sizeof (keytab) / sizeof (struct keytab))
                /*whole bytes      bytes in element*/

struct keytab
  {
   char *keyword;
   int keycount;
  }
 keytab[]={
         "auto", 0,
         "break", 0,
         "case",0,
         "char", 0,
         "const", 0,
         "continue", 0,
         "default", 0,
         "do", 0,
         "double", 0,
         "else", 0,
         "enum", 0,
         "extern", 0,
         "float", 0,
         "for", 0,
         "goto", 0,
         "if", 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 binsearch(char word, struct keytab, int n);
int getword(char w, int lim);

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

  while ((t = getword(word, MAXWORD)) !=EOF)
    if (t== LETTER)
        if (n = binsearch(word, keytab, NKEYS)) >= 0)
          keytab[n].keycount++;

  for (n=0; n < NKEYS; n++)
     if (keytab[n].keycount >0)
        printf("%4d %s\n", keytab[n].keycount, keytab[n].keyword);
}

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

  low=0;
  high = n-1;
  while (low <= high)
    {
        mid = (low+high)/2;
        if (( cond =strcmp(word, tab[mid].keyword)) < 0)
           high = mid -1;

        else if (cond >0)
           low = mid +1;

        else
           return(mid);
   }
return (-1)
}

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

  if (type(c = *w++ = getch()) != LETTER)
   {
    *w = '\0';
    return(c);
   }

   while (-- lim > 0)
        {
        t = type (c = *w++ = getch());
        if (t != LETTER && t != DIGIT)
          {
           ungetch(c);
           break;
          }
        }
  *(w-1) = '\0';
  return(LETTER);
}
type(c)  /* return type of ASCII character */
int c;
{
  if (c >= 'a' && c <= 'z' || c >= 'A' && c <= 'Z')
     return(LETTER);
  else if (c >= '0' && c <= '9')
     return(DIGIT);
  else
     return(c);
}

"keyword.c", line 56: warning: improper pointer/integer combination: arg #1
"keyword.c", line 58: warning: improper pointer/integer combination: arg #1
"keyword.c", line 58: argument #2 is incompatible with prototype:
prototype: struct keytab {pointer to char keyword, int keycount} : "keyword.c", line 48
argument : pointer to struct keytab {pointer to char keyword, int keycount}
"keyword.c", line 58: syntax error before or at: >=
"keyword.c", line 64: cannot recover from previous errors

Ok worked out most of the bugs but now win I compile it I get an undefined symbol error.

#include <stdio.h>
#include <string.h>
#include <ctype.h>
#define MAXWORD 20
#define LETTER 'a'
#define DIGIT '0'
#define NKEYS (sizeof (keytab) / sizeof (struct keytab))
                /*whole bytes      bytes in element*/

struct keytab
  {
   char *keyword;
   int keycount;
  }
 keytab[]={
         "auto", 0,
         "break", 0,
         "case",0,
         "char", 0,
         "const", 0,
         "continue", 0,
         "default", 0,
         "do", 0,
         "double", 0,
         "else", 0,
         "enum", 0,
         "extern", 0,
         "float", 0,
         "for", 0,
         "goto", 0,
         "if", 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 binsearch(char word[], struct keytab keytab[], int n);
int getword(char *w, int lim);
int getch(void);
void ungetch(int);

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

  while ((t = getword(word, MAXWORD)) !=EOF)
    if (t== LETTER)
        if (n = binsearch(word, keytab, NKEYS) >= 0)
          keytab[n].keycount++;

  for (n=0; n < NKEYS; n++)
     if (keytab[n].keycount >0)
        printf("%4d %s\n", keytab[n].keycount, keytab[n].keyword);
}

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

  low=0;
  high = n-1;
  while (low <= high)
    {
        mid = (low+high)/2;
        if (( cond =strcmp(word, keytab[mid].keyword)) < 0)
           high = mid -1;

        else if (cond >0)
           low = mid +1;

        else
           return(mid);
   }
return (-1);
}

/* getop: get next operator or numeric operand */
int getop(char s[])
{
  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 = getchar()))
        ;
  s[i] = '\0';
  if (c != EOF)
    ungetch(c);
  return DIGIT;
}

int type(int c)  /* return type of ASCII character */
{
  if (c >= 'a' && c <= 'z' || c >= 'A' && c <= 'Z')
     return(LETTER);
  else if (c >= '0' && c <= '9')
     return(DIGIT);
  else
     return(c);
}

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

  if (type(c = *w++ = getch()) != LETTER)
   {
    *w = '\0';
    return(c);
   }

   while (-- lim > 0)
        {
        t = type (c = *w++ = getch());
        if (t != LETTER && t != DIGIT)
          {
           ungetch(c);
           break;
          }
        }
  *(w-1) = '\0';
  return(LETTER);
}

(14) unixs1 $ cc keyword.c
Undefined first referenced
symbol in file
getch keyword.o
ungetch keyword.o
ld: fatal: Symbol referencing errors. No output written to a.out

Ok worked out most of the bugs but now win I compile it I get an undefined symbol error.

(14) unixs1 $ cc keyword.c
Undefined first referenced
symbol in file
getch keyword.o
ungetch keyword.o
ld: fatal: Symbol referencing errors. No output written to a.out

And this is exactly why we recommend that you guys should not use compiler-specific non-standard functions when you code. Those functions listed do not exist in your compiler. But do people listen? Noooooooooooo.... :icon_twisted:

Yea after re-reading the code a fifth time I saw the getop didn't have getch and ungetch functions defined in them. created the functions and its finished.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.