C语言实现通讯录(动态内存分配空间和保存文件和读取文件)

本文介绍了如何使用C语言实现一个通讯录系统,包括动态内存分配存储联系人信息,以及文件保存和读取功能。系统在退出时会自动保存联系人到messege.txt文件,启动时可选择读取该文件。读取文件时,通过换行符判断并解析不同属性。代码中详细解释了如何处理字符串属性的修改,并提供了动态调整内存空间的策略,确保能存储所有联系人。
摘要由CSDN通过智能技术生成

上一篇文章,我写了一个简单的动态内存分配空间的通讯录,这一篇文章,我已经将其改成了每次使用完通讯录系统退出时,会自动的保存到文件里,准备进入通讯录系统的时候,可以选择是否读取上次保存文件里的联系人,如果选择读取,那必须,要有messege.txt文件,如果没有会给出提示,那你就可以选择不读取,执行一次,就直接自动生成一个messege.txt文件

注意:如果结构体变量,里面的属性是字符串,如果要修改,要通过strcpy函数来修改

先给大家我的思路:

	退出时,联系人存入文件:
  1. 先要定义一个规则
  2. 每个人通讯录人的每个属性都存一行,一个人存5行,再存个换行
  3. 方便读取文件时,根据换行符的个数%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);
}
	进入通讯录是,读取文件:
  1. 定义一个count,表示遇到的第几个\n
  2. 一次读取一个字符,然后保存到一个字符数组里,
  3. 如果读到字符为\n,如果count%6等于1,就把字符串放入,name里面
  4. 如果读到字符为\n,如果count%6等于2,就把字符串放入,age里面
  5. 如果读到字符为\n,如果count%6等于3,就把字符串放入,sex里面
  6. 如果读到字符为\n,如果count%6等于4,就把字符串放入,phone里面
  7. 如果读到字符为\n,如果count%6等于5,就把字符串放入,adress里面
  8. 如果读到字符为\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)
  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值