【问题标题】:Create link list from text file从文本文件创建链接列表
【发布时间】:2025-12-12 22:00:01
【问题描述】:

无法读取文本文件并将其存储在链接列表中。我正在读取具有名字、l 名称、优先级和阅读级别的文件。我相信问题可能是我没有正确分配字符串/tempPtr,或者我的循环一直在运行。运行程序时,它一直在运行,没有段错误。

typedef struct Student{
    char* firstName;
    char* lastName;
    int priority;
    int readingLevel;
    bookIds* wishlist;
    struct Student* next;
}student;    

student* buildStudentList(char* studentsFile, student* head)
{
    int i;
    FILE* fp;
    student* tempPtr = NULL;
    if((fp = fopen(studentsFile, "r")) == NULL)
        {
            printf("Unable to open file\n");
            return 0;
        }

    student* current = NULL;
    tempPtr = (student*)malloc(sizeof(student));
    tempPtr->firstName = malloc(sizeof(char)* NAME);
    tempPtr->lastName = malloc(sizeof(char)* NAME);

    while(fscanf(fp, "%s %s %d %d",tempPtr->firstName, tempPtr->lastName, tempPtr->priority, tempPtr->readingLevel) != EOF)
        {
            tempPtr->next = NULL;
            if(head == NULL)
                {
                    head = tempPtr;
                    current = tempPtr;
                    tempPtr = (student*)malloc(sizeof(student));
                }
            else
                {
                    current->next = tempPtr;
                    current = tempPtr;
                    tempPtr = (student*)malloc(sizeof(student));
                }
        }
    free(tempPtr);
    fclose(fp);
    return head;
}

【问题讨论】:

  • 使用调试器准确地找出程序在哪里循环,以及此时链表的样子。这是调试此类小程序的正确方法。只有在您自己用尽所有调试途径后才转向 *。
  • 开启完整的编译器警告。您的fscanf() 通话有问题,应该是&tempPtr->priority&tempPtr->readingLevel
  • 每次分配另一个student时,都需要为tempPtr->firstNametempPtr->lastName分配空间。也许你应该在结构中将它们声明为数组而不是指针。

标签: c malloc singly-linked-list


【解决方案1】:

我建议您更改student 结构,使firstNamelastName 是数组而不是指针。当它们的大小始终相同时,无需使用动态分配。

typedef struct Student{
    char firstName[NAME];
    char lastName[NAME];
    int priority;
    int readingLevel;
    bookIds* wishlist;
    struct Student* next;
}student;

接下来,每当你分配一个新的student,你需要初始化wishListnext指向NULL的指针。

当您调用fscanf() 时,您需要将指针传递给您正在填写的int 成员。

您可以通过在一个地方执行malloc() 来简化您的代码,而不是在循环之前然后在if 的每个分支中重复它。将输入读入局部变量,然后在成功后分配student

typedef struct Student{
    char firstName[NAME];
    char lastName[NAME];
    int priority;
    int readingLevel;
    bookIds* wishlist;
    struct Student* next;
}student;    

student* buildStudentList(char* studentsFile, student* head)
{
    int i;
    FILE* fp;
    if((fp = fopen(studentsFile, "r")) == NULL)
        {
            printf("Unable to open file\n");
            return 0;
        }

    student* current = NULL;

    char firstName[NAME], lastName[NAME];
    int priority, readingLevel;

    while(fscanf(fp, "%s %s %d %d",firstName, lastName, &priority, &readingLevel) != EOF)
        {
            student* tempPtr = malloc(sizeof(student));
            tempPtr->next = NULL;
            tempPtr->wishlist = NULL;
            strcpy(tempPtr->firstName, firstName);
            strcpy(tempPtr->lastName, lastName);
            tempPtr->priority = priority;
            tempPtr->readingLevel = readingLevel;

            if(head == NULL)
                {
                    head = tempPtr;
                }
            else
                {
                    current->next = tempPtr;
                }
            current = tempPtr;
        }
    fclose(fp);
    return head;
}

【讨论】:

  • 好的,所以现在当我在 main 中调用这个函数时,我遇到了段错误。我在似乎没有问题的函数中逐行运行。主要我把它作为head = buildStudentList(student,head)。其中 head = NULL 并且 student 的 char 类型设置为 argv[1]。
  • 我刚试了一下,效果很好。也许你在程序的其他地方有问题。
  • 好的,这就是它在 main 中的调用方式。不太确定我在哪里可以得到这个段错误问题。运行 GDB,但似乎没有准确显示段错误的来源。 int main(int argc, char* argv[]) { if (argc 4) { printf("无效使用程序\n");返回0; } 字符* 文件 = argv[1]; //char* 愿望清单 = argv[2];学生*首先 = NULL; first = buildStudentList(file, first); //打印学生(头);返回0; }
  • 如果我注释掉该函数,我不会遇到段错误问题。
  • 这并不意味着问题出在这个函数上。如果您有未定义的行为,则可能会导致不相关代码中的错误。