Hi!
When I try to compile the program from K&R (using -Werror -Wall -Wextra -pedantic), I get this warning (the full program is below):
warning: comparison between signed and unsigned
which refers to this line:
Code:
for (n = 0; n < NKEYS; n++)
I see that I have declared n as an int, and NKEYS is an unsigned type.
But I can't change n for sure, because binsearch function might
return -1, hence I need signed int.
As to NKEYS, sizeof returns size_t value, which is, as said in K&R,
is an unsigned type.
I wonder why this error occurs in code from K&R and they do not refer
to it. Is there a way to overcome this issue?
Code:
/* Program to count the occurences of each C keyword */
#include <stdio.h>
#include <ctype.h>
#include <string.h>
#include <stddef.h>
struct key
{
char *word;
int count;
} keytab[] =
{
{"auto", 0},
{"break", 0},
{"case", 0},
{"char", 0},
{"const", 0},
{"continue", 0},
{"default", 0},
/* ... */
{"unsigned", 0},
{"void", 0},
{"volatile", 0},
{"while", 0}
};
#define MAXWORD 100
#define NKEYS (sizeof keytab / sizeof(struct key))
/* same as #define NKEYS (sizeof keytab / sizeof keytab[0]) */
int getword(char *, int);
int binsearch(char *, struct key *, int);
/*count C keywords */
int main(void)
{
int n;
char word [MAXWORD];
while (getword(word, MAXWORD) != EOF)
{
if (isalpha(word[0]))
{
if ((n = binsearch(word, keytab, NKEYS)) >= 0)
{
keytab[n].count++;
}
}
}
for (n = 0; n < NKEYS; n++)
{
if (keytab[n].count > 0)
{
printf("%4d %s\n",
keytab[n].count, keytab[n].word);
}
}
return 0;
}
/* GETCH and UNGETCH functions */
#define BUFSIZE 100
/* buffer for ungetch */
static char buf[BUFSIZE];
/* next free position in buf */
static int bufp = 0;
/* get a (possibly pushed back) character */
int getch (void)
{
return (bufp > 0) ? buf[--bufp] : getchar();
}
/* push character back on input */
void ungetch (int c)
{
if (bufp >= BUFSIZE)
{
printf("ungetch: too many characters\n");
}
else
{
buf[bufp++] = c;
}
}
/* getword: get next word or characer from input */
int getword (char *word, int lim)
{
int c, getch(void);
void ungetch(int);
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];
}
/* binsearch: 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;
}
return -1;
}
Thank you!