c中的链表结构与read txt

时间:2016-03-13 20:42:29

标签: c data-structures struct linked-list e-commerce

pitcure

我上传上面的图片。我问问题,如何从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);

1 个答案:

答案 0 :(得分:0)

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

while (fscanf(fp, "%d\t%s\t%s", &CustomerId, CustomerName, CustomerSurname) != EOF)
  • 您应该通过告知CustomerName要存储到这些数组中的最大字符数来防止CustomerSurnamefscanf中的缓冲区溢出:请使用格式"%d\t%19s\t%19s"。< / LI>
  • 您只检查文件末尾的fscanf完全失败,它将返回EOF,但它会返回已解析的字段数,您应该检查这是3 。如果fscanf无法解析第一个字段的整数,它将返回0并且所有字段的内容将保持不变。您将无限期地循环添加相同的新记录到列表中,直到malloc最终返回NULL时您崩溃,而您不进行测试。
  • 格式字符串中的\t字符将匹配文件中的任何空格字符序列,而不仅仅是TAB字符。这可能与您的预期不同。请注意,%d%s都会忽略前导空白字符,因此格式字符串中的\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);