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
要存储到这些数组中的最大字符数来防止 CustomerName
和 CustomerSurname
中的缓冲区溢出:为此使用格式 "%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);
我上传了上面的图片。我问问题,如何从 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
要存储到这些数组中的最大字符数来防止CustomerName
和CustomerSurname
中的缓冲区溢出:为此使用格式"%d\t%19s\t%19s"
. - 你只检查文件末尾的
fscanf
完全失败,它会 returnEOF
,但它 return 是解析的字段数,你应该检查它是否为3
。如果fscanf
第一个字段解析整数失败,则return0
,所有字段内容不变。您将无限期地向列表中添加相同的新记录,直到当malloc
最终 returnNULL
时崩溃,您没有测试。 - 格式字符串中的
\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);