链表中的结构

Structs in Linked List

我对 C 编程还很陌生,遇到了一些麻烦。 我编写了一些代码来读取一个文件,该文件包含有关人名、年龄、体重和身高的信息。文件中的每一行都代表一个新人。然后将此信息存储在结构中,然后将此结构添加到链表中。本质上,我正在尝试将此链表用作队列,每个节点都是一个结构。

这就是我正在阅读的文件的样子:(格式为年龄、体重、身高、姓名)。

20,60,170,Joe
23,70,175,Mike 

我的问题是,由于某种原因,链表中的每个节点都完全相同,即文件文本的最后一行。因此,例如,每次我创建一个结构并将其添加到链表时,每个节点都将具有名称 'Mike'、年龄“23”等。我已经尝试过代码,我注意到文件读取没有问题,并且分配给结构成员的值是正确的(我打印出要检查的值)。但是,当我查看链接列表的顶部,然后出列(删除顶部),然后再次查看顶部时,值始终相同。所以我不确定我的问题出在哪里。

注意:我写了一个通用的链表代码,经过大量测试,链表本身没有问题。

这是我的代码:

#include <stdio.h>
#include "macros.h"
#include <string.h>

typedef struct
{
    int AGE;
    int WEIGHT;
    int HEIGHT;
    char NAME[51];
}Person;

int main()
{
    void* vdPtr;
    Person* topVal;
    Person person; 
    LinkedList* list = createLinkedList();
    char line[100];
    int i=0;
    int numPeople=0;
    FILE* fp;
    int age, weight, height;
    char name[51];
    fp = fopen("text.txt","r");
    
    while(fgets(line,100,fp) != NULL)/*reading file to see how many lines, and how many people*/
    {
        numPeople++;
    }

    rewind(fp);

    while (i<numPeople)/*storing file data in the appropriate member for Person struct*/
    {
        fscanf(fp,"%d,%d,%d,%s",&age,&weight,&height,name);
        person.AGE = age;
        person.WEIGHT = weight;
        person.HEIGHT = height;
        strcpy(person.NAME,name);
        insertLast(list,&person);
        /*printing to see whether the values added to struct members are correct*/
        printf("%d %d %d %s\n",person.AGE,person.WEIGHT,person.HEIGHT,person.NAME);
        i++;
    }

    /*testing*/
    printf("\nCount %d",getLinkedListCount(list));/*seeing how many nodes in the linkedList*/
    
    /*using void pointer to get the top value, then typecasting it to Person pointer*/
    vdPtr = viewTop(list);
    topVal = (Person*)(vdPtr); 
    
    /*viewing the top person*/
    printf("\ntop is %s %d",topVal->NAME,topVal->AGE);
    
    /*deqeue*/
    removeTop(list);
    printf("\nCount %d",getLinkedListCount(list));
    
    vdPtr = viewTop(list);
    topVal = (Person*)(vdPtr);
    printf("\ntop is %s %d",topVal->NAME,topVal->AGE);
}

谁能告诉我哪里出错了以及如何解决?

您不断地向列表中添加相同的指针。在每一行你覆盖相同的变量。所以最后你有一大堆指针都指向同一个东西。你必须像这样为每个人创建一个新的 person 结构:

#include <stdio.h>
#include "macros.h"
#include <string.h>

typedef struct
{
    int AGE;
    int WEIGHT;
    int HEIGHT;
    char NAME[51];
}Person;

int main()
{
    void* vdPtr;
    Person* topVal;


    LinkedList* list = createLinkedList();
    char line[100];
    int i=0;
    int numPeople=0;
    FILE* fp;
    int age, weight, height;
    char name[51];
    fp = fopen("text.txt","r");
    
    while(fgets(line,100,fp) != NULL)/*reading file to see how many lines, and how many people*/
    {
        numPeople++;
    }

    rewind(fp);

    while (i<numPeople)/*storing file data in the appropriate member for Person struct*/
    {
        Person *person = (Person *)malloc(sizeof(Person)); //make new person object

        fscanf(fp,"%d,%d,%d,%s",&age,&weight,&height,name);
        person->AGE = age;
        person->WEIGHT = weight;
        person->HEIGHT = height;
        strcpy(person->NAME, name);
        insertLast(list, person);
        
        /*printing to see whether the values added to struct members are correct*/
        printf("%d %d %d %s\n",person.AGE,person.WEIGHT,person.HEIGHT,person.NAME);
        i++;
    }

    /*testing*/
    printf("\nCount %d",getLinkedListCount(list));/*seeing how many nodes in the linkedList*/
    
    /*using void pointer to get the top value, then typecasting it to Person pointer*/
    vdPtr = viewTop(list);
    topVal = (Person*)(vdPtr); 
    
    /*viewing the top person*/
    printf("\ntop is %s %d",topVal->NAME,topVal->AGE);
    
    /*deqeue*/
    removeTop(list);
    printf("\nCount %d",getLinkedListCount(list));
    
    vdPtr = viewTop(list);
    topVal = (Person*)(vdPtr);
    printf("\ntop is %s %d",topVal->NAME,topVal->AGE);
}

我建议阅读指针和内存管理的工作原理。另请记住,此代码不会释放它分配的内存,这是您仍然需要做的事情。

没有看到 insertLast() 的代码也很难回答,但您可能会为每个人创建一个新结构,然后将其传递给 insertLast :

Person* newPerson;
while (i<numPeople)/*storing file data in the appropriate member for Person struct*/
{
   newPerson = (Person *)malloc(sizeof(Person))
    fscanf(fp,"%d,%d,%d,%s",&age,&weight,&height,name);
    newPerson->AGE = age;
    newPerson->WEIGHT = weight;
    newPerson->HEIGHT = height;
    strcpy(newPerson.NAME,name);
    insertLast(list,newPerson);
    ...

列表好像只保存了数据的地址,所以需要为每个人创建新的数据。

要在链表中使用的struct需要是自引用的。即其中一个成员(通常是最后一个)是指向结构本身的指针。这就是允许将数据段链接在一起的原因。 (其他成员可以被认为是有效负载或数据。)例如,您的结构:

typedef struct
{
    int AGE;
    int WEIGHT;
    int HEIGHT;
    char NAME[51];
}Person;

可以重构为:

struct Person 
{
    int AGE;
    int WEIGHT;
    int HEIGHT;
    char NAME[51];
    struct Person *node;
};

查看 creating and using linked lists 的简单入门教程。 (单击 C 选项卡查看示例代码。)