在c语言中向双链表中添加结构

在c语言中向双链表中添加结构,c,struct,doubly-linked-list,C,Struct,Doubly Linked List,我是编程新手(第一学期),在做作业的时候,我在这里找到的例子对我帮助很大! 现在我要做一个稍微大一点的项目,我已经读了很多书,但我就是解决不了这个问题 我被要求做什么 从文件的文本中读取数据 通过strok() (通过将从文件读取的数据分配给结构字段,将其放入结构中) 将结构添加到双链接列表中 问题 当我打印列表时,列表中只有第一个和最后一个结构,中间的结构消失了(第一个条目“head”与pNode=head;一起在main中定义) 如果我尝试按正向顺序打印列表,它将无限打印最后一个列表元素 我

我是编程新手(第一学期),在做作业的时候,我在这里找到的例子对我帮助很大! 现在我要做一个稍微大一点的项目,我已经读了很多书,但我就是解决不了这个问题

我被要求做什么
  • 从文件的文本中读取数据
  • 通过
    strok()
    (通过将从文件读取的数据分配给结构字段,将其放入结构中)
  • 将结构添加到双链接列表中
  • 问题
  • 当我打印列表时,列表中只有第一个和最后一个结构,中间的结构消失了(第一个条目“head”与
    pNode=head;
    一起在main中定义)
  • 如果我尝试按正向顺序打印列表,它将无限打印最后一个列表元素
  • 我试着只复制我认为对这个问题很重要的部分。 由于我已经尝试了这么多,我甚至不知道在哪里寻找错误了,任何帮助或提示是感激的。非常感谢

    void read_file(struct node *pNode, FILE *fp) {
        struct node *head = pNode;
        head->next=NULL;
        head->prev=NULL;
    
        /*(fread, strtok_r, strtok,...)*/
    
        while (token1 != NULL) {
            //allocating memory for the structs
            struct node*new = calloc(1, sizeof(struct node));
            *new =*pNode;
    
            while (token2 != NULL) {
                new->index = (*token2 - 48);
                token2 = strtok(NULL, "\n"); //jump to next token (=next line)
    
                new->name = malloc(sizeof(char)*strlen(new->name)+1);
                strcpy(new->name, token2);
                token2 = strtok(NULL, "\n");
    
                /*(some more sorting into struct)*/
    
                /*ADD STRUCT TO LIST*/
    
                if (head->next==NULL){
                    head->next=new;
                    head->prev=NULL;
                    new->prev=head;
                    new->next=NULL;
                }
    
                new->next = head->next;
                head->next = new;
                new->next->prev = new;
                new->prev = head;
                head->prev = NULL;
    
                pNode=new;
            }
    
            token_recipe = strtok_r(NULL, "#", &temp); //jump to next token (=next recipe)
        }
    
        printf("\nLinked list in backwards order:\n");
    
        while (pNode != NULL) {
            printf("%s ", pNode->name);
            pNode= pNode->prev;
        }
        puts("\n");
    }
    

    你这里有一个乱七八糟的纠结,我会尽力帮你解开

            if (head->next==NULL){
                head->next=new;
                head->prev=NULL;
                new->prev=head;
                new->next=NULL;
            }
    
            new->next = head->next;
            head->next = new;
            new->next->prev = new;
            new->prev = head;
            head->prev = NULL;
    
    你第一次有
    head->next
    NULL
    ,因此您在
    if
    块中执行该位,并最终得到如下列表:

    头新

    然后您将
    new->next
    指向
    head->next
    …这意味着您将
    new->next
    指向
    new

    头新->新

    new->next->prev=new
    因此
    new->prev
    现在也等于
    new

    头->新-新

    但随后您将其修复为指向
    head
    ,并将
    head->prev
    设置为
    NULL
    ,因为您从未更改过它

    头新->新

    您仍然有
    new
    的循环循环指向自身作为下一个节点

    完全废弃那个代码
    pNode
    是列表中的上一个节点,最初与
    head
    相同-这是您应该链接到的变量

    new->prev = pNode;
    pNode->next = new;
    
    未指定的上一个值和下一个值应已设置为
    NULL
    (因为您正在使用
    calloc
    )或指向内存中的有效位置,这样您就不需要对它们进行处理

    然后在循环结束时正确地执行以下操作

    pNode = new;
    
    将列表的末尾指向最新创建的节点

    您还应该去掉以下行,因为
    new
    是一个新的节点-在
    pNode
    中不应该有任何内容要复制,因此您正在设置您不想要的下一个和上一个值,因为它们已经正确设置为
    NULL

    *new =*pNode;
    

    你这里有一个乱七八糟的纠结,我会尽力帮你解开

            if (head->next==NULL){
                head->next=new;
                head->prev=NULL;
                new->prev=head;
                new->next=NULL;
            }
    
            new->next = head->next;
            head->next = new;
            new->next->prev = new;
            new->prev = head;
            head->prev = NULL;
    
    你第一次有
    head->next
    NULL
    ,因此您在
    if
    块中执行该位,并最终得到如下列表:

    头新

    然后您将
    new->next
    指向
    head->next
    …这意味着您将
    new->next
    指向
    new

    头新->新

    new->next->prev=new
    因此
    new->prev
    现在也等于
    new

    头->新-新

    但随后您将其修复为指向
    head
    ,并将
    head->prev
    设置为
    NULL
    ,因为您从未更改过它

    头新->新

    您仍然有
    new
    的循环循环指向自身作为下一个节点

    完全废弃那个代码
    pNode
    是列表中的上一个节点,最初与
    head
    相同-这是您应该链接到的变量

    new->prev = pNode;
    pNode->next = new;
    
    未指定的上一个值和下一个值应已设置为
    NULL
    (因为您正在使用
    calloc
    )或指向内存中的有效位置,这样您就不需要对它们进行处理

    然后在循环结束时正确地执行以下操作

    pNode = new;
    
    将列表的末尾指向最新创建的节点

    您还应该去掉以下行,因为
    new
    是一个新的节点-在
    pNode
    中不应该有任何内容要复制,因此您正在设置您不想要的下一个和上一个值,因为它们已经正确设置为
    NULL

    *new =*pNode;
    

    您希望
    *new=*pNode
    做什么?这种“将其排序为结构”让我感到困惑。您可能是指“排序到结构数组”或其他涉及更大数据结构的内容。考虑重新措词来降低像我这样迷惑别人的风险。包括一个非常基本的主要功能可能有助于理解你的问题。无论如何,这可能是尝试调试器的最佳时机。;)@Yunnosch我将“将其排序为结构”这句话解释为“通过将从文件读取的数据分配给结构字段,将其放置到结构中”。Nezuko,我说的对吗?@Cubo78我明白你的意思,我读到“同一类数据的多个实例,按字母顺序排序……”。但是“将不同类型的数据中的每个实例排序到结构的适当类型字段中”是有道理的。关键是我设法误解了,假设我不是理解最慢的人,为清晰起见重新措辞可能是值得的。你期望
    *new=*pNode
    做什么?这种“将其排序为结构”让我困惑。您可能是指“排序到结构数组”或其他涉及更大数据结构的内容。考虑重新措词来降低像我这样迷惑别人的风险。包括一个非常基本的主要功能可能有助于理解你的问题。无论如何,这可能是尝试调试器的最佳时机。;)@Yunnosch我已经解释了