Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.c > #164680

on looking up a word in a table, pointer question

From Meredith Montgomery <mmontgomery@levado.to>
Newsgroups comp.lang.c
Subject on looking up a word in a table, pointer question
Date 2022-01-28 18:16 -0300
Organization Aioe.org NNTP Server
Message-ID <86k0ejbly8.fsf@levado.to> (permalink)

Show all headers | View raw


I show the full program at the end of this message, but I bet you don't
need the full program.  

Here's a table of C keywords:

--8<---------------cut here---------------start------------->8---
struct kw {
  char *word; 
  int count;
};

struct kw table[] = {
  {"break", 0},
  {"case", 0},
  {"char", 0},
  {"const", 0},
  {"int", 0},
  {"continue", 0},
  {"default", 0},
  {"unsigned", 0},
  {"void", 0},
  {"volatile", 0},
  {"while", 0}
};
--8<---------------cut here---------------end--------------->8---

Here's a procedure to lookup a word in this table:

--8<---------------cut here---------------start------------->8---
struct kw * lookup(char *word, struct kw * table, int n) {
  struct kw *p;

  for ( p = table; p->word != NULL; p++) {
    if (strcmp(word, p->word) == 0)
      return p;
  }

  return NULL; /* not found */
}
--8<---------------cut here---------------end--------------->8---

Notice how I'm stopping when p->word is not NULL.  This happens when p
gets to the last element of that array, which is terminated with a zero
automatically by the compiler.  (Just like a c-string.)  (I suppose.)

So far so good. 

But this is not what I wrote first.  I'm stepping p through each element
in the table, so I know that eventually p points to the last element of
the array which is a certain zero-thing.  So the more natural comparison
to me would be something like 

  *p != NULL

but the compiler won't let me because it says that *p has type 

  struct kw, 

which cannot be compared with 

  void *.  

%make keywords2
cc -x c -g -std=c99 -pedantic-errors   -c -o keywords2.o keywords2.c
keywords2.c: In function ‘lookup’:
keywords2.c:48:23: error: invalid operands to binary != (have ‘struct kw’ and ‘void *’)
   48 |   for ( p = table; *p != NULL; p++) {
      |                    ~~ ^~
      |                    |
      |                    struct kw
make: *** [<builtin>: keywords2.o] Error 1
%

This makes perfect sense.  But how could I detect that p has reached the
end of the table in a more natural way than p->word?  What is the
standard way to write this?  Thank you.

(*) Full program

#include <ctype.h>
#include <string.h>
#include <stdio.h>

#define NKEYS ((sizeof table) / (sizeof table[0]))
#define MAXWORD 100

int getword(char *, int);
struct kw * lookup(char *, struct kw *, int);

struct kw {
  char *word; 
  int count;
};

struct kw table[] = {
  {"break", 0},
  {"case", 0},
  {"char", 0},
  {"const", 0},
  {"int", 0},
  {"continue", 0},
  {"default", 0},
  {"unsigned", 0},
  {"void", 0},
  {"volatile", 0},
  {"while", 0}
};

int main() {
  int n; char word[MAXWORD]; struct kw * p;

  while (getword(word, MAXWORD) != EOF)
    if (isalpha(word[0]))
      if ((p = lookup(word, table, NKEYS)) != NULL)
        p->count++;

  for (p = table; p < table + NKEYS; p++)
    if (p->count > 0)
      printf("%4d %s\n", p->count, p->word);

  return 0;
}

struct kw * lookup(char *word, struct kw * table, int n) {
  struct kw *p;

  for ( p = table; *p != NULL; p++) {
    if (strcmp(word, p->word) == 0)
      return p;
  }

  return NULL; /* not found */
}

int getword(char *word, int lim) {
  int getch(void);
  void ungetch(int);

  int c; 
  char *w = word;

  while (isspace(c = getch()))
    ;

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

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

  for ( ; --lim > 0; w++)
    if (!isalnum(*w = getch())) {
      ungetch(*w);
      break;
    }

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

Back to comp.lang.c | Previous | NextNext in thread | Find similar | Unroll thread


Thread

on looking up a word in a table, pointer question Meredith Montgomery <mmontgomery@levado.to> - 2022-01-28 18:16 -0300
  Re: on looking up a word in a table, pointer question scott@slp53.sl.home (Scott Lurndal) - 2022-01-28 21:29 +0000
  Re: on looking up a word in a table, pointer question Meredith Montgomery <mmontgomery@levado.to> - 2022-01-28 18:49 -0300
  Re: on looking up a word in a table, pointer question Kaz Kylheku <480-992-1380@kylheku.com> - 2022-01-28 22:07 +0000
    Re: on looking up a word in a table, pointer question Meredith Montgomery <mmontgomery@levado.to> - 2022-01-28 22:03 -0300
  Re: on looking up a word in a table, pointer question Ben Bacarisse <ben.usenet@bsb.me.uk> - 2022-01-28 22:23 +0000
    Re: on looking up a word in a table, pointer question Meredith Montgomery <mmontgomery@levado.to> - 2022-01-28 22:05 -0300
    Re: on looking up a word in a table, pointer question James Kuyper <jameskuyper@alumni.caltech.edu> - 2022-01-28 21:10 -0500
  Re: on looking up a word in a table, pointer question Lew Pitcher <lew.pitcher@digitalfreehold.ca> - 2022-01-28 22:27 +0000
    Re: on looking up a word in a table, pointer question Lew Pitcher <lew.pitcher@digitalfreehold.ca> - 2022-01-28 23:18 +0000
      Re: on looking up a word in a table, pointer question Ben Bacarisse <ben.usenet@bsb.me.uk> - 2022-01-29 02:32 +0000
        Re: on looking up a word in a table, pointer question Meredith Montgomery <mmontgomery@levado.to> - 2022-01-30 10:23 -0300
          Re: on looking up a word in a table, pointer question Bart <bc@freeuk.com> - 2022-01-30 13:44 +0000
    Re: on looking up a word in a table, pointer question Mike Terry <news.dead.person.stones@darjeeling.plus.com> - 2022-01-28 23:23 +0000

csiph-web