标题:求肋,C程序设计语言练习6-3,程序为什么会崩溃?感觉是p->word的值出问题了 ...
只看楼主
marlow
Rank: 6Rank: 6
等 级:侠之大者
威 望:2
帖 子:125
专家分:419
注 册:2016-7-18
结帖率:75%
已结贴  问题点数:20 回复次数:4 
求肋,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;
}
搜索更多相关主题的帖子: C程序设计 include numbers linked points 
2016-11-26 12:53
九转星河
Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19
来 自:长长久久
等 级:贵宾
威 望:52
帖 子:5023
专家分:14003
注 册:2016-10-22
得分:20 
程序代码:
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->lines=talloc();//这里,linklist 与tonde不是同一个结构体,固linklist要另外申请储存空间
        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;
}

p->lines=talloc();//这里,linklist 与tonde不是同一个结构体,固linklist要另外申请储存空间
不过,运行结果要你自己慢慢去调试~

[此贴子已经被作者于2016-11-26 13:19编辑过]


[code]/*~个性签名:bug是什么意思?bug是看上去没有可能的东西实际上是有可能做到的 就是这样~2018-08-08更~*/[/code]
2016-11-26 13:17
九转星河
Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19
来 自:长长久久
等 级:贵宾
威 望:52
帖 子:5023
专家分:14003
注 册:2016-10-22
得分:0 
还有,我只是修改一个地方就能正常运行了。我很好奇题主编译这么长的代码而且程序正确率那么高,在没法正常运行的情况下是怎么样确保整体程序的正确性的(如果是我,我也许起码要调试几十次才能正常实现功能)。有没有看过什么参考还是按自己的套路编译的?题主编写该程序要用多长时间啊~

其实,我也想学习一下如何尽可能在编译的同时也就是在调试之前保证程序的正确性(特别是编译大型程序的时候),因为我编译经常出错以至于用尽可能多的调试来慢慢纠正,但感觉这样编译效率不是太理想。

[code]/*~个性签名:bug是什么意思?bug是看上去没有可能的东西实际上是有可能做到的 就是这样~2018-08-08更~*/[/code]
2016-11-26 13:49
marlow
Rank: 6Rank: 6
等 级:侠之大者
威 望:2
帖 子:125
专家分:419
注 册:2016-7-18
得分:0 
谢谢,确实是这样的
我找了好久都没发现。。。

一切都在学习、尝试、摸索中
2016-11-26 14:03
marlow
Rank: 6Rank: 6
等 级:侠之大者
威 望:2
帖 子:125
专家分:419
注 册:2016-7-18
得分:0 
回复 3楼 九转星河
我是看了参考提示的。。。
另外,平时积累了一些代码,如getword() getch()等函数,只要遇到类似的问题就加进去,不用重新写
水平还很低,需多加学习、练习
谢谢九转星河的帮助!!!

一切都在学习、尝试、摸索中
2016-11-26 14:10



参与讨论请移步原网站贴子:https://bbs.bccn.net/thread-471610-1-1.html




关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.128434 second(s), 8 queries.
Copyright©2004-2024, BCCN.NET, All Rights Reserved