简体   繁体   English

具有读取txt的c中的链表结构

[英]linked list struct in c with read txt

固化

I upload picture above. 我在上面上传图片。 I ask question, how can I read from txt files to add linked list with structs. 我问一个问题,我如何从txt文件读取信息以添加带有结构的链表。 I try this but how can I declare for basket.txt and produce .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);

There is a subtile problem in your code: the way you parse the input file is incorrect: 您的代码中有一个小问题:解析输入文件的方式不正确:

while (fscanf(fp, "%d\t%s\t%s", &CustomerId, CustomerName, CustomerSurname) != EOF)
  • you should protect from buffer overflows in CustomerName and CustomerSurname by telling fscanf the maximum number of characters to store into these arrays: use format "%d\\t%19s\\t%19s" for that. 您应通过告诉fscanf存储在这些数组中的最大字符数来防止CustomerNameCustomerSurname的缓冲区溢出:为此,请使用格式"%d\\t%19s\\t%19s"
  • you only check for fscanf complete failure at end of file, where it would return EOF , but it returns the number of fields parsed and you should check for this to be 3 . 您仅在文件末尾检查fscanf完全失败,它将返回EOF ,但它返回已解析的字段数,因此应检查是否为3 If fscanf fails to parse an integer for the first field, it will return 0 and the contents of all fields will be unchanged. 如果fscanf无法为第一个字段解析整数,它将返回0并且所有字段的内容都将保持不变。 You will loop indefinitely adding the same new record to the list, until you crash when malloc will eventually return NULL , which you do not test. 您将无限循环地将相同的新记录添加到列表中,直到崩溃时malloc最终将返回NULL ,而您无需测试。
  • The \\t character in the format string will match any sequence of white space characters in the file, not just the TAB character. 格式字符串中的\\t字符将匹配文件中的任何空白字符序列,而不仅仅是TAB字符。 This may be different from what you expect. 这可能与您的预期有所不同。 Note that %d and %s both ignore leading white space characters, so the \\t characters in the format string are completely redundant. 请注意, %d%s都忽略前导空格字符,因此格式字符串中的\\t字符是完全多余的。

There are other issues, such as 还有其他问题,例如

  • You do not check for fopen failure 您不检查fopen失败
  • You do not check for memory allocation failure 您不检查内存分配失败

Here is an improved version: 这是一个改进的版本:

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);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM