链表不能正常工作

Linked list doesn't function properly

我正在尝试使用链接列表从文本文件中提取文本。到目前为止我的代码:

#include <stdlib.h>
#include <string.h>
#define N 20
struct node
{
    char * str;
    struct node * node;
};
typedef struct node Node;
typedef Node * WordList;
typedef Node * Node_ptr;
void addtext(WordList * lst_ptr);
void report(WordList words);
Node * createnode(char *str);

int main(void)
{
    WordList words = NULL;
    addtext(&words);
    report(words);
    return 0;
}
Node * createnode(char *str)
{
    Node_ptr newnode_ptr ;
    newnode_ptr = malloc(sizeof (Node));
    newnode_ptr -> str = NULL;
    newnode_ptr -> node = NULL;
    return newnode_ptr;
}

void addtext(WordList * lst_ptr)
{
    FILE *fileinput;
    char word[N];
    char *pnt;
    if ((fileinput = fopen("test.txt", "rt"))==NULL)
    {
        printf("Cannot open file. Please check if the file is in the right directory and you are giving the correct name.");
        exit(EXIT_FAILURE);
    }
    while (fscanf(fileinput, "%19s", word)  == 1)
    {

        Node * newnode = createnode(word);
        if (*lst_ptr==NULL)
        {
            newnode->node = *lst_ptr;
            *lst_ptr = newnode;
        }
        else
        {
            Node *iter;
            for (iter = *lst_ptr; iter -> node != NULL; iter = iter -> node);
            iter -> node = newnode;
        }
        pnt = strtok (word," ");
        while (pnt != NULL)
        {
            newnode->str = pnt;
            pnt = strtok (NULL, " ");
        }
    }
    fclose(fileinput);

    return ;
}

void report(WordList words)
{
    if (words == NULL)
    {
        printf("\n") ;
        return ;
    }
    printf("%s\n",words -> str);
    report(words -> node);
    return;
}

我制作的文本文件包含以下内容:

Hello
Bye

但是我程序的输出是:

Bye
(random characters)

意思是打印最后一个字。我的猜测是,当我调用 report 时,它指向列表的最后一个元素,并从那里继续移动与文本文件中的单词数量一样多的次数。 我还在报告功能上尝试了不同的方法:

void report(WordList words)
{
    Node * iter;
    for (iter = words; iter!=NULL; iter = iter->node)
    {
        printf("%s\n", iter->str);
    }
    return;
}

但现在它会打印 \n 直到循环结束。我是漏掉了什么简单的东西还是犯了一个严重的错误?

strtok() 修改原始字符串和 returns 指向原始字符串元素的指针。在这种情况下,原始字符串存储在本地数组 char word[N]; 中。本地数组将在返回函数 addtext 时消失,并且从函数 report 引用数组是非法的。

为了避免这个麻烦,您应该分配一些新区域并将字符串复制到那里。可以这样做:

pnt = strtok (word," ");
while (pnt != NULL)
{
    newnode->str = malloc(strlen(pnt) + 1); /* allocate a region (+1 for terminating null-character) */
    if (newnode->str == NULL) /* check if allocation succeeded */
    {
        /* handle allocation failure */
        exit(1);
    }
    strcpy(newnode->str, pnt); /* copy the string */
    pnt = strtok (NULL, " ");
}

简化版:

newnode->str = strdup(pnt);