上一篇文章,我写了一个简单的动态内存分配空间的通讯录,这一篇文章,我已经将其改成了每次使用完通讯录系统退出时,会自动的保存到文件里,准备进入通讯录系统的时候,可以选择是否读取上次保存文件里的联系人,如果选择读取,那必须,要有messege.txt文件,如果没有会给出提示,那你就可以选择不读取,执行一次,就直接自动生成一个messege.txt文件
注意:如果结构体变量,里面的属性是字符串,如果要修改,要通过strcpy函数来修改
先给大家我的思路:
退出时,联系人存入文件:
- 先要定义一个规则
- 每个人通讯录人的每个属性都存一行,一个人存5行,再存个换行
- 方便读取文件时,根据换行符的个数%6的值判断存的是什么属性
代码:
//在退出通讯录的时候把信息到保存到文件中
void save_File(const char* fileName,list* p){
FILE* fp = fopen(fileName, "w+");
if (fp == NULL){
printf("FILE OPEN ERREO!!\n");
return;
}
//每个人通讯录人的每个属性都存一行,一个人存5行,再存个换行
for (int i = 0; i < p->count; i++){
fprintf(fp,"%s\n",p->num[i].name); //存姓名
fprintf(fp,"%s\n",p->num[i].age); //存年龄
fprintf(fp,"%s\n",p->num[i].sex); //存性别
fprintf(fp,"%s\n",p->num[i].phone); //存电话
fprintf(fp,"%s\n",p->num[i].address); //存地址
fprintf(fp, "\n");
fflush(fp);
}
fclose(fp);
}
进入通讯录是,读取文件:
- 定义一个count,表示遇到的第几个\n
- 一次读取一个字符,然后保存到一个字符数组里,
- 如果读到字符为\n,如果count%6等于1,就把字符串放入,name里面
- 如果读到字符为\n,如果count%6等于2,就把字符串放入,age里面
- 如果读到字符为\n,如果count%6等于3,就把字符串放入,sex里面
- 如果读到字符为\n,如果count%6等于4,就把字符串放入,phone里面
- 如果读到字符为\n,如果count%6等于5,就把字符串放入,adress里面
- 如果读到字符为\n,如果count%6等于0,那么就把p指向的count++
代码:
// 添加一个函数,在通讯录打开的时候,可以把文件中的信息加载到通讯录中
void load_File(const char* fileName, list* p){
FILE* fp = fopen(fileName, "r");
if (fp == NULL){
printf("FILE LOAD ERREO!!\n");
return;
}
//定义一个count,表示遇到的第几个\n
//一次读取一个字符,然后保存到一个字符数组里,
//如果读到字符为\n,如果count%6==1,就把字符串放入,name里面
//如果读到字符为\n,如果count%6==0,那么就把p指向的count++
char c;
int count = 0;
char str[50] = {
'\0' };
int i = 0; //str下标
while ((c = fgetc(fp)) != -1){
if (c != '\n'){
str[i] = c;
i++;
}
else{
str[i] = '\0'; //就算遇到/0,也要添加到str,不然录取姓名为徐文文,年龄就变成20文
i++;
count++;
if (count % 6 == 1){
strcpy(p->num[p->count].name, str); //结构体变量的内容的修改,如果是字符串,必须用strcpy修改
i = 0; //清空
}
else if (count % 6 == 2){
strcpy(p->num[p->count].age, str);
i = 0; //清空
}
else if (count % 6 == 3){
strcpy(p->num[p->count].sex, str);
i = 0; //清空
}
else if (count % 6 == 4){
strcpy(p->num[p->count].phone, str);
i = 0; //清空
}
else if (count % 6 == 5){
strcpy(p->num[p->count].address, str);
i = 0; //清空
}
else if (count % 6 == 0){
p->count += 1;
i = 0; //清空
}
else{
printf("load error!\n");
return;
}
}
}
fclose(fp);
printf("读取成功,欢迎光临(:\n");
}
注意:读取文件之前,要判断有多少个联系人,看开始开辟的10个练习人的空间够不够,如果不够再开辟,通过扫描文件换行符的个数/6等于联系人的个数,如果联系人的个数>=10,则让记录换行符的count一直++,直到%10等于0为止,然后再开辟空间,如果小于10,就可以不用管
代码:
int load_FILE_Flag = 1;
printf("请选择是否读取上一次存入联系人的文件?\n"); //如果没有文件需要自己在项目路径下创建,或者选择0,第一次过后,自动生成文件
printf("####### 1.yes 0.no #######\n");
scanf("%d", &load_FILE_Flag);
if (load_FILE_Flag){
//先要读取文件里有多少个/n,然后除以6,如果>=10,
//把zeroCount/=6,然后让其%10==0,如果不余0,就zeroCount++,
//最后再把spaceSize=zeroCount,然后再给p开辟更大的空间
FILE* fp = fopen("messege.txt", "r");
int zeroCount = 0; //换行符的数量
char ch;
while ((ch=fgetc(fp)) != -1){
if (ch == '\n'){
zeroCount += 1;
}
}
if ((zeroCount = zeroCount / 6) >= 10){
//现在zeroCount就知道文件里存了几个Person数据了,然后让其变成%10==0
while ((zeroCount % 10) != 0)