c中的链表结构,读取txt

linked list struct in c with read txt

我上传了上面的图片。我问问题,如何从 txt 文件中读取以添加带有结构的链表。我试试这个,但我如何声明 basket.txt 并生成 .txt

FILE *fp
char CustomerName[20];
char CustomerSurname[20];
int  CustomerId;
struct Customer *current = NULL, *head = NULL;
fp = fopen("customer.txt", "r");

while (fscanf(fp, "%d\t%s\t%s", &CustomerId, CustomerName, CustomerSurname) != EOF) {
    struct Customer *ReadList;
    ReadList = (struct Customer *)malloc(sizeof(struct Customer));
    ReadList->NextPtr = NULL;
    ReadList->CustomerId = CustomerId;
    ReadList->CustomerName = strdup(CustomerName);
    ReadList->CustomerSurname = strdup(CustomerSurname);
    if (head == NULL) {
        current = head = ReadList;
    } else {
        current = current->NextPtr = ReadList;
    }
}
fclose(fp);

您的代码中存在一个微妙的问题:您解析输入文件的方式不正确:

while (fscanf(fp, "%d\t%s\t%s", &CustomerId, CustomerName, CustomerSurname) != EOF)
  • 您应该通过告诉 fscanf 要存储到这些数组中的最大字符数来防止 CustomerNameCustomerSurname 中的缓冲区溢出:为此使用格式 "%d\t%19s\t%19s" .
  • 你只检查文件末尾的 fscanf 完全失败,它会 return EOF,但它 return 是解析的字段数,你应该检查它是否为 3。如果fscanf第一个字段解析整数失败,则return0,所有字段内容不变。您将无限期地向列表中添加相同的新记录,直到当 malloc 最终 return NULL 时崩溃,您没有测试。
  • 格式字符串中的 \t 字符将匹配文件中任何白色 space 字符序列,而不仅仅是 TAB 字符。这可能与您的预期不同。请注意 %d%s 都忽略前导白色 space 字符,因此格式字符串中的 \t 字符完全多余。

还有其他问题,比如

  • 您没有检查 fopen 故障
  • 你没有检查内存分配失败

这是一个改进版本:

FILE *fp
char CustomerName[20];
char CustomerSurname[20];
int  CustomerId;
int res;
struct Customer *current = NULL, *head = NULL;
fp = fopen("customer.txt", "r");
if (fp == NULL) {
    fprintf(stderr, "cannot open input file\n");
    return 1;
}

while ((res = fscanf(fp, "%d\t%19s\t%19s", &CustomerId, CustomerName, CustomerSurname)) == 3) {
    struct Customer *ReadList = malloc(sizeof(*ReadList));
    if (ReadList == NULL) {
        fprintf(stderr, "cannot allocate memory for customer\n");
        fclose(fp);
        return 1;
    }
    ReadList->NextPtr = NULL;
    ReadList->CustomerId = CustomerId;
    ReadList->CustomerName = strdup(CustomerName);
    ReadList->CustomerSurname = strdup(CustomerSurname);
    if (ReadReadList->CustomerName == NULL || ReadList->CustomerSurname == NULL) {
        fprintf(stderr, "cannot allocate memory for customer fields\n");
        fclose(fp);
        return 1;
    }
    if (head == NULL) {
        current = head = ReadList;
    } else {
        current = current->NextPtr = ReadList;
    }
}
if (res != EOF) {
    fprintf(stderr, "input file has incorrect format\n");
    fclose(fp);
    return 1;
}
fclose(fp);