c - 从文件读取到链表 C
问题描述
我正在尝试读取一个 txt 文件,然后将其保存到 C 中的链表中。我尝试了很多,但我还没有找到解决方案。
这就是我所拥有的:
typedef struct contact{
char name[50];
char number[10];
char bithday[15];
struct contact *next;
}contact;
struct contact *head;
FILE *fp;
这部分将我已经拥有的联系人保存到 txt 文件中。
void backup(){
struct contact *ap;
fp=fopen("save_contacts.txt", "w");
if(fp==NULL){
printf(" Error\n");
system("pause");
return 1;
}
for (ap=head;ap!=NULL;ap=ap->next){
fprintf(fp,"%s ",ap->name);
//fprintf(fp,", ");
fprintf(fp,"%s ",ap->number);
//fprintf(fp,", ");
fprintf(fp,"%s ",ap->birthday);
//fprintf(fp,", ");
fprintf(fp,"; ");
}
fprintf(fp, "End");
}
所以我的问题在于这部分,它不读取 txt 文件。
void read() {
struct contact *ap;
int i;
head=NULL;
char aux[30];
FILE *fp=fopen("save_contacts.txt","r");
do{
head=NULL;
ap=(contact*)malloc(sizeof(contact));
fscanf(fp,"%s ",&ap->name);
fscanf(fp,"%s ",&ap->number);
fscanf(fp,"%s ",&ap->birthday);
fscanf(fp,"%s ",aux);
if(strcmp(aux,";")==0){
ap=ap->next;
}
}while(strcmp(aux,"End")!=0);
}
解决方案
Doing
ap=(contact*)malloc(sizeof(contact)); fscanf(fp,"%s ",&ap->name); fscanf(fp,"%s ",&ap->number); fscanf(fp,"%s ",&ap->birthday); fscanf(fp,"%s ",aux); if(strcmp(aux,";")==0){ ap=ap->next;
ap->next
is not set so the second turn ap has an undefined value so the behavior is undefined when you dereference it
Note your way to save with :
for (ap=head;ap!=NULL;ap=ap->next){ ... fprintf(fp,"; "); } fprintf(fp, "End");
is not compatible with your way to read where ';' is replaced by 'End' for the last element
You can do that (I suppose there is no ';' for the last element) :
int read() {
FILE *fp=fopen("save_contacts.txt","r");
if (fp == NULL) {
fprintf(stderr, "cannot open 'save_contacts.txt'\n");
head = NULL;
return 0;
}
contact ** pp = &head;
char aux[30];
int result;
for (;;) {
*pp = malloc(sizeof(contact));
if (fscanf(fp,"%49s %9s %14s %29s", (*pp)->name, (*pp)->number, (*pp)->birthday, aux) != 4) {
fputs("invalid file, cannot read the 3 fields then ;/End\n", stderr);
result = 0;
free(*pp);
break;
}
pp = &(*pp)->next;
if (strcmp(aux,"End") == 0) {
result = 1;
break;
}
if (strcmp(aux, ";") != 0) {
fputs("invalid file, expected ; or End\n", stderr);
result = 0;
break;
}
}
*pp = NULL;
fclose(fp);
return result;
}
returning 0 in case of a problem, else 1
Note I protect the read of the string to not write out of them and I check if the file is correct
For instance having the full program
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct contact{
char name[50];
char number[10];
char birthday[15]; /* not bithday */
struct contact *next;
}contact;
struct contact *head;
int read() {
FILE *fp=fopen("save_contacts.txt","r");
if (fp == NULL) {
fprintf(stderr, "cannot open 'save_contacts.txt'\n");
head = NULL;
return 0;
}
contact ** pp = &head;
char aux[30];
int result;
for (;;) {
*pp = malloc(sizeof(contact));
if (fscanf(fp,"%49s %9s %14s %29s", (*pp)->name, (*pp)->number, (*pp)->birthday, aux) != 4) {
fputs("invalid file, cannot read the 3 fields then ;/End\n", stderr);
result = 0;
free(*pp);
break;
}
pp = &(*pp)->next;
if (strcmp(aux,"End") == 0) {
result = 1;
break;
}
if (strcmp(aux, ";") != 0) {
fputs("invalid file, expected ; or End\n", stderr);
result = 0;
break;
}
}
*pp = NULL;
fclose(fp);
return result;
}
int main()
{
if (read()) {
/* debug */
for (contact * p = head; p != NULL; p = p->next)
printf("%s %s %s\n", p->name, p->number, p->birthday);
}
/* free resources */
while (head != NULL) {
contact * p = head;
head = head->next;
free(p);
}
return 0;
}
Compilation and execution:
pi@raspberrypi:/tmp $ gcc -pedantic -Wextra -Wall l.c
pi@raspberrypi:/tmp $ cat save_contacts.txt
bruno 007 19/02/1960 ;
you 001 01/01/2010 ;
bar 123 31/12/1999 End
pi@raspberrypi:/tmp $ ./a.out
bruno 007 19/02/1960
you 001 01/01/2010
bar 123 31/12/1999
pi@raspberrypi:/tmp $
Execution under valgrind :
pi@raspberrypi:/tmp $ valgrind ./a.out
==2334== Memcheck, a memory error detector
==2334== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==2334== Using Valgrind-3.13.0 and LibVEX; rerun with -h for copyright info
==2334== Command: ./a.out
==2334==
bruno 007 19/02/1960
you 001 01/01/2010
bar 123 31/12/1999
==2334==
==2334== HEAP SUMMARY:
==2334== in use at exit: 0 bytes in 0 blocks
==2334== total heap usage: 6 allocs, 6 frees, 5,712 bytes allocated
==2334==
==2334== All heap blocks were freed -- no leaks are possible
==2334==
==2334== For counts of detected and suppressed errors, rerun with: -v
==2334== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 6 from 3)
pi@raspberrypi:/tmp $
推荐阅读
- r - 在 Blogdown 新项目中安装 Infinity Hugo 主题
- php - Can't access Phpmyadmin in ubuntu error mysqli_real_connect(): (HY000/2002)
- python - 有没有办法从 anaconda 发行版中卸载 VScode,然后重新安装它作为“新的开始”?
- python-3.x - 如何将 drake 的优化工具箱与 mujoco-py 模拟器结合起来?
- ios - 场景委托不更新视图控制器
- string - 如何在flutter中从json字符串创建列表
- postgresql - knex(postgres)引用另一个表中的列(不是唯一的)
- python - 如何从 Django 中的 2 个不同模型中获取数据
- python - Django:根据 URL slug 查询两个表
- python - TensorFlow Github 存储库中定义的 Softmax 函数