C 添加到同一地址的链表节点

C 添加到同一地址的链表节点,c,linked-list,malloc,C,Linked List,Malloc,我正在读一个UTF-8格式的文本文件,使用fgetc和分隔词。我创建了一个append函数来将每个单词添加到一个链表中,但是当我打印出单词的地址时,它们都是相同的,这表明它们只是被覆盖了。如何正确地将数据添加到列表中 我还做了一个打印指令来遍历列表,尽管数据在append函数中正确打印出来,但print函数只给出了一个垃圾值 struct node { void *data; struct node *next; }; 我在链接列表中键入def 每次我得到一个新词时,我都在ma

我正在读一个UTF-8格式的文本文件,使用fgetc和分隔词。我创建了一个append函数来将每个单词添加到一个链表中,但是当我打印出单词的地址时,它们都是相同的,这表明它们只是被覆盖了。如何正确地将数据添加到列表中

我还做了一个打印指令来遍历列表,尽管数据在append函数中正确打印出来,但print函数只给出了一个垃圾值

struct node
{
    void *data;
    struct node *next;
};
我在链接列表中键入def

每次我得到一个新词时,我都在main中调用append函数

void append(linked_list *list, void *word)
{

    if(list->data == NULL)
    {
        list->data = word;
        list->next = NULL;
                //printf("WORD: %s\n", (char *)list->data);
        //printf("ADDRESS %p\n", list->data);
    }
    else
    {
        linked_list *new_node;
        new_node = malloc(sizeof(linked_list));
        new_node->data = word;
        new_node->next = NULL;

        while(list->next != NULL)
        {
            if(list->next == NULL)
            {
                list->next = new_node;
            }

        }
                //printf("WORD: %s\n", (char *)list->data);
        //printf("ADDRESS %p\n", list->data);

    }

}
这是我的打印功能

void print_list(linked_list *list) {

    if(list == NULL)
    {
        printf("Print: the list is empty!\n");
    }

    while (list != NULL) {
        printf("DATA %s\n", (char *)list->data);
        list = list->next;
    } 

}
我希望打印功能可以打印

所有的单词都是“数据单词”,但我得到的是“数据单词”

附加函数中的打印提供:

WORD: The
ADDRESS 0x55b6fa2314b0

WORD: Project
ADDRESS 0x55b6fa2314b0

WORD: Gutenberg
ADDRESS 0x55b6fa2314b0

WORD: EBook
ADDRESS 0x55b6fa2314b0

WORD: of
ADDRESS 0x55b6fa2314b0

WORD: Pride
ADDRESS 0x55b6fa2314b0

WORD: and
ADDRESS 0x55b6fa2314b0

WORD: Prejudice,
ADDRESS 0x55b6fa2314b0

WORD: by
ADDRESS 0x55b6fa2314b0

WORD: Jane
ADDRESS 0x55b6fa2314b0

WORD: Austen
ADDRESS 0x55b6fa2314b0

问题在于这一部分:

while(list->next != NULL)
{
    if(list->next == NULL)
    {
        list->next = new_node;
    }

}
您不会转到下一个节点,而是始终位于第一个节点中。复制
列表
(不要更改列表本身)并迭代:

linked_list *copy = list;

while(copy->next != NULL)
{
    copy = copy->next;
}

copy->next = new_node;



这个程序有很多问题

  • 空列表的表示形式。看起来您选择了用一个没有数据的虚拟节点来表示一个空列表。虽然这本身在技术上并没有错,但这并不是最直观、最直接的表示。通常,空列表仅用空指针表示。有关更多信息,请参阅
  • 加法循环是错误的。现在还不清楚你的函数如何能在一个列表中添加多个节点

    while(list->next != NULL)
    {
        // at this point, list->next != NULL, by definition (see loop condition)
        if(list->next == NULL) // this is always false
        {
            list->next = new_node; // this is never executed
        }
        // the loop body doesn't modify anything
    }
    
    另一个答案有办法纠正这一点,我在这里不再重复

  • 最后但并非最不重要的一点是,您所抱怨的错误是由错误导致的

  • “它们都是一样的”--是的,因为您可能会将它们扫描到同一个缓冲区,然后只存储该缓冲区的地址。存储字符串时,应复制该字符串。(
    strdup
    可能有用,但不是一个标准函数。)现在还不清楚这个程序如何做任何事情,因为
    while(list->next!=NULL)
    循环永远不会终止。这仍然给了我相同的输出!打印功能?我应该提到,当我在valgrind下运行程序时,它确实给了我正确的数据和不同的地址。当我运行它时,我会得到所有单词的垃圾值<代码>无效打印列表(链接列表*列表){if(list==NULL){printf(“打印:列表为空!\n”);}而(list!=NULL){printf(“数据%s\n”,(char*)列表->数据);list=list->next;}但是你在哪里打印地址?@js\u hammer08你需要发布一个而不是一组随意编辑的片段。你链接的问题的解决方案解决了这个问题。我得到数据,并将其存储在正确的地址。但是,你能解释一下,首先将数据复制到另一个指针中实际上会有什么不同吗?@js_hammer08你需要了解数组和指针在C中是如何工作的,它们之间有什么区别,以及它们之间的联系是什么。这远远超出了这个答案的范围。