求肋,C程序设计语言练习6-3,程序为什么会崩溃?感觉是p->word的值出问题了
/* crossreferencer.c: 交叉引用程序,打印文档中所有单词的列表,并且每个单词还有一个列表,记录出现过该单词的行号,对the,and等非实义单词不予考虑。 */
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include <stdlib.h>
#define MAXWORD 100
struct linklist { /* linked list of line numbers */
int lnum;
struct linklist *ptr;
};
struct tnode { /* the tree node; */
char *word; /* points to the text */
struct linklist *lines; /* line numbers */
struct tnode *left; /* left child */
struct tnode *right; /* right child */
};
struct tnode *addtreex(struct tnode *, char *, int);
int getword(char *, int);
int noiseword(char *);
void treexprint(struct tnode *);
/* crosee-referencer */
int main(void)
{
struct tnode *root;
char word[MAXWORD];
int linenum = 1;
root = NULL;
while(getword(word, MAXWORD) != EOF)
if(isalpha(word[0]) && noiseword(word) == -1)
root = addtreex(root, word, linenum);
else if(word[0] == '\n')
linenum++;
treexprint(root);
return 0;
}
struct tnode *talloc(void);
struct linklist *l_alloc(void);
void addln(struct tnode *, int);
char *strd_up(char *);
/* addtreex: add a node with w, st or below p */
struct tnode *addtreex(struct tnode *p, char *w, int linenum)
{
int cond;
if(p == NULL){ /* a new word has arrived */
p = talloc(); /* make a new word */
p->word = strd_up(w);
p->lines->lnum = linenum;
p->lines->ptr = NULL;
p->left = p->right = NULL;
}else if((cond = strcmp(w, p->word)) == 0){
addln(p, linenum);
}else if(cond < 0){
p->left = addtreex(p->left, w, linenum);
}else if(cond > 0){
p->right = addtreex(p->right, w, linenum);
}
return p;
}
/* addln: add a line number to the linked list */
void addln(struct tnode *p, int linenum)
{
struct linklist *temp;
temp = p->lines;
while(temp->ptr != NULL && temp->lnum != linenum)
temp = temp->ptr;
if(temp->lnum != linenum){
temp->ptr = l_alloc();
temp->ptr->lnum = linenum;
temp->ptr->ptr = NULL;
}
}
/* treexprint: ln-order print of tree p */
void treexprint(struct tnode *p)
{
struct linklist *temp;
if(p != NULL){
treexprint(p->left);
printf("%10s: ", p->word);
for(temp = p->lines; temp != NULL; temp = temp->ptr)
printf("%4d ", temp->lnum);
printf("\n");
treexprint(p->right);
}
}
/* lalloc: make a linklist node */
struct linklist *l_alloc(void)
{
return (struct linklist *)malloc(sizeof(struct linklist));
}
/* talloc函数:创建一个tnode */
struct tnode *talloc(void)
{
return (struct tnode *)malloc(sizeof(struct tnode));
}
/* strd_up函数:把通过其参数传入的字符串复印到某个安全的位置。*/
char *strd_up(char *s) /* 复印S到某个位置 */
{
char *p;
p = (char *) malloc(strlen(s) + 1); /* 执行加1操作是为了在结尾加上字符'\0' */
if(p != NULL)
strcpy(p, s);
return p;
}
/* noiseword: identity word as a noise word */
int noiseword(char *w)
{
static char *nw[] = {
"a",
"an",
"and",
"are",
"in",
"is",
"of",
"or",
"that",
"the",
"this",
"to"
};
int cond, mid;
int low = 0;
int high = sizeof(nw) / sizeof(char *) - 1;
while(low <= high){
mid = (low + high) / 2;
if((cond = strcmp(w, nw[mid])) < 0)
high = mid - 1;
else if(cond > 0)
low = mid + 1;
else
return mid;
}
return -1;
}
/* getword函数: 从输入中读取下一个单词或字符*/
int getword(char *word, int lim)
{
int c, d, comment(void), getch(void);
void ungetch(int);
char *w = word;
while(isspace(c = getch()) && c != '\n')
;
if(c != EOF)
*w++ = c;
if(isalpha(c) || c == '_' || c == '#'){
for( ; --lim > 0; w++)
if(!isalnum(*w = getch()) && *w != '_'){
ungetch(*w);
break;
}
}else if(c == '\'' || c == '"'){
for(; --lim > 0; w++)
if((*w = getch()) == '\\')
*++w = getch();
else if(*w == c){
w++;
break;
}else if(*w == EOF)
break;
}else if(c == '/'){
if((d = getch()) == '*')
c = comment();
else
ungetch(d);
}
*w = '\0';
return c;
}
#define BUFSIZE 100
char buf[BUFSIZE]; /* 用于ungetch函数的缓冲区 */
int bufp = 0; /* buf中下一个空闲位置*/
int getch(void) /* 取一个字符(可能是压回的字符)*/
{
return (bufp > 0) ? buf[--bufp] : getchar();
}
void ungetch(int c) /* 把字符压回到输入中*/
{
if(bufp >= BUFSIZE)
printf("ungetch: too many characters\n");
else
buf[bufp++] = c;
}
/* comment: skip over comment and return a character */
int comment(void)
{
int c;
while((c = getch()) != EOF)
if(c == '*')
if((c = getch()) == '/')
break;
else
ungetch(c);
return c;
}