程序在迭代链表时崩溃

时间:2016-06-16 16:56:00

标签: c linked-list

我应该创建一个包含以下属性的链表:

struct node{
    char *word;
    int times;
    struct node *next;
}head;

我必须从文件中读取每个单词,检查它是否存在于列表中,如果它不存在,我应该添加它。如果它已经存在,我需要将times增加一个。我使用以下代码来实现:

void append(char *wrd, struct node *start){
    struct node *current = start;

    while(current->next != NULL){
        current = current->next;
    }
    current->next = malloc(sizeof(struct node));
    strcpy(current->word, wrd);
    current->times = 1;
    current->next->next = NULL;

}

int iterate(char *wrd, struct node *start){
    struct node *current = start;

    while(current != NULL){

        if(strcmp(current->word, wrd)==0){
            current->times++;
            return 1;
        }
        current = current->next;

    }

    return 0;
}

void read_file(struct node *start){

    FILE *fp;
    char wrd[20];
    puts("give file name and format(max 19 characters)");
    gets(wrd);

    fp = fopen((const char*)wrd, "r");
    fscanf(fp, "%s", wrd);
    start->word = malloc(strlen(wrd)+1);
    strcpy(start->word, wrd);

    while(fscanf(fp, "%s", wrd) != EOF){

        if(!iterate(wrd, start)){
            append(wrd, start);
        }       

    }

}

void print_data(struct node *start){
    struct node *current = start;
    while(current->next != NULL){
        printf("word: %s , times: %d", current->word, current->times);
    }
}

int main(int argc, char *argv[]) {
    struct node *start = &head;
    read_file(start);
    return 0;
}

append接受一个字,创建一个包含它的新节点,并将该节点添加到列表中。

iterate接受一个单词并在列表中搜索匹配项。如果列表中已存在该单词,则times将增加1。如果未找到匹配项,则会返回0,而在相反的情况下会返回1

read_file初始化头节点,读取文件并为其读取的每个单词调用上述函数。

假设我有一个包含以下字词的文本文件:

hello hey world hello
world this is supposed to work
but it does not

程序成功运行前3个单词并创建节点。找到匹配hello后,程序崩溃。我已经确定错误在于iterate,但我无法弄清楚导致它的原因。非常感谢任何帮助。

1 个答案:

答案 0 :(得分:0)

首先,我不明白为什么你可以自信地说你的程序在iterate函数中有错误。

word之前,您尚未向strcpy()指针分配任何内存。 我建议你在append()函数中执行此操作:

void append(char *wrd, struct node *start){
    struct node *current = start;
    if(current == NULL){
        start = (struct node*)malloc(sizeof(struct node));
        start->word = (char *)malloc((strlen(wrd) + 1)*sizeof(char));
        strcpy(start->word, wrd);
        start->times = 1;
        start->next = NULL;
        return;
    }
    while(current->next != NULL){
        current = current->next;
    }
    current->next = (struct node*)malloc(sizeof(struct node));
    current->next->word = (char*)malloc((strlen(wrd) + 1)*sizeof(char)); //add this line
    strcpy(current->next->word, wrd); //not current->word
    current->next->times = 1; //not current->times
    current->next->next = NULL;
}

请注意,在append函数中,您没有检查列表是否已经为空。 if块也是这样做的。还要注意使用strcpy()时犯的错误。您希望在新指针中复制新单词,但是在指针中执行它,该指针是新节点的父指针。

现在,您read_file()功能看起来会简单得多!

 void read_file(struct node *start){

    FILE *fp;
    char wrd[20];
    puts("give file name and format(max 19 characters)");
    gets(wrd);

    fp = fopen((const char*)wrd, "r");
    while(fscanf(fp, "%s", wrd) != EOF){

        if(!iterate(wrd, start)){
            append(wrd, start);
        }       

    }

}

我认为您的iterate功能不需要更新,但print_data()肯定会:

void print_data(struct node *start){
    struct node *current = start;
    while(current != NULL){
        printf("word: %s , times: %d", current->word, current->times);
        current = current->next;
    }
}

似乎唯一没有任何错误的函数是iterate()。当你玩指针时会发生! :P