c_动态、存储到文件通讯录

 

实现一个通讯录;
通讯录可以用来存储1000个人的信息,每个人的信息包括:
姓名、性别、年龄、电话、住址
提供方法:
1. 添加联系人信息
2. 删除指定联系人信息
3. 查找指定联系人信息
4. 修改指定联系人信息
5. 显示所有联系人信息
6. 清空所有联系人
7. 以名字排序所有联系人
在动态版本(可见c_动态通讯录)的基础上将通讯录实现成文件存储的版本。

 

思想:用二进制流写入和读取文件。详细知识具体可见c_I/O文件存储

在每次退出前,写入时将整个柔性数组写入

在每次运行操作前,读取时一次读取一个联系人结构体大小;

关于起始读取文件的联系人至柔性数组中的空间问题:在将文件存储的联系人全部读取到柔性数组中后,修改数组开辟空间的大小,使用realloc函数,完成数组空间扩充问题。详细知识具体可见c_动态内存管理

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<Windows.h>

#pragma warning(disable:4996)

#define nameSize 8
#define telSize 12
#define addrSize 20

/*
实现一个通讯录;
通讯录可以用来存储1000个人的信息,每个人的信息包括:
姓名、性别、年龄、电话、住址
提供方法:
1. 添加联系人信息
2. 删除指定联系人信息
3. 查找指定联系人信息
4. 修改指定联系人信息
5. 显示所有联系人信息
6. 清空所有联系人
7. 以名字排序所有联系人
将通讯录实现成文件存储的版本。
*/

typedef struct information{
	char name[nameSize];
	char sex;
	int age;
	char tel[telSize];
	char addr[addrSize];
}Note;

typedef struct flexible{
	int personNum;//当前的联系人数
	Note arrNote[0];//柔性结构体数组
}fNote;

void menu()
{
	printf("***************************************\n");
	printf("************  通讯录选项  *************\n");
	printf("***************************************\n");
	printf("******* 1、添加联系人信息       *******\n");
	printf("******* 2、删除指定联系人信息   *******\n");
	printf("******* 3、查找指定联系人信息   *******\n");
	printf("******* 4、修改指定联系人信息   *******\n");
	printf("******* 5、显示所有联系人信息   *******\n");
	printf("******* 6、清空所有联系人       *******\n");
	printf("******* 7、以名字排序所有联系人 *******\n");
	printf("******* 0、退出                 *******\n");
	printf("***************************************\n");
	printf("please input your choice:");
}

void myAdd(fNote *fnote, int personSum)
{
	printf("please input information<name sex age tel addr>:\n");
	Note note;
	scanf("%s %c %d %s %s", note.name, &(note.sex), &(note.age), note.tel, note.addr);
	if (personSum > fnote->personNum){
		*(fnote->arrNote + (fnote->personNum)++) = note;
		printf("add succeed!\n");
	}
	else{
		printf("address book is Full!\n");
	}
}

void myDelete(fNote *fnote)
{
	printf("please input the person of name you want to delete:");
	char tmp[nameSize];
	scanf("%s", tmp);
	int i = 0;
	while (i < fnote->personNum){
		if (!strcmp(fnote->arrNote[i].name, tmp)){
			if (fnote->personNum == 1){
				fnote->personNum = 0;
				return;
			}
			//将数组添加的最后一个元素移至此覆盖当前值
			fnote->arrNote[i] = *(fnote->arrNote + (fnote->personNum - 1));
			(fnote->personNum)--;
			printf("delete succeed!\n");
			return;
		}
		i++;
	}
	printf("There is no this person!\n");
}

void myFind(fNote *fnote)
{
	printf("please input the person of name you want to find:");
	char tmp[nameSize];
	scanf("%s", tmp);
	int i = 0;
	while (i < fnote->personNum){
		if (!strcmp(fnote->arrNote[i].name, tmp)){
			printf("name:%-10ssex:%-5cage:%-5dtel:%-15saddr:%-22s\n", fnote->arrNote[i].name, \
				fnote->arrNote[i].sex, fnote->arrNote[i].age, fnote->arrNote[i].tel, fnote->arrNote[i].addr);
			return;
		}
		i++;
	}
	printf("There is no this person!\n");
}

void myModify(fNote *fnote)
{
	printf("please input the person of name you want to modify:");
	char tmp[nameSize];
	scanf("%s", tmp);
	int i = 0;
	while (i < fnote->personNum){
		if (!strcmp(fnote->arrNote[i].name, tmp)){
			printf("please input information<name sex age tel addr>:\n");
			scanf("%s %c %d %s %s", fnote->arrNote[i].name, &(fnote->arrNote[i].sex), \
				&(fnote->arrNote[i].age), fnote->arrNote[i].tel, fnote->arrNote[i].addr);
			printf("modify succeed!\n");
			return;
		}
		i++;
	}
	printf("There is no this person!\n");
}

void myShow(fNote *fnote)
{
	int i = 0;
	if (!fnote->personNum){
		printf("no one!\n");
	}
	while (i < fnote->personNum){
		printf("name:%-10ssex:%-5cage:%-5dtel:%-15saddr:%-22s\n", fnote->arrNote[i].name, \
			fnote->arrNote[i].sex, fnote->arrNote[i].age, fnote->arrNote[i].tel, fnote->arrNote[i].addr);
		i++;
	}
}

void myClear(fNote *fnote)
{
	fnote->personNum = 0;
	printf("clear succeed!\n");
}


int myCmpNote(const void * note1, const void *note2)
{
	Note *x = (Note *)note1;
	Note *y = (Note *)note2;
	int res = strcmp((*x).name, (*y).name);
	if (res > 0){
		return 1;
	}
	else if (res < 0){
		return -1;
	}
	else{
		return 0;
	}
}

void mySort(fNote *fnote)
{
	int tmp = fnote->personNum;
	qsort(fnote->arrNote, tmp, sizeof(Note), myCmpNote);
	myShow(fnote);
}

void branch(fNote *fnote, int sel, int personSum)
{
	switch (sel){
	case 1:
		myAdd(fnote, personSum);
		break;
	case 2:
		myDelete(fnote);
		break;
	case 3:
		myFind(fnote);
		break;
	case 4:
		myModify(fnote);
		break;
	case 5:
		myShow(fnote);
		break;
	case 6:
		myClear(fnote);
		break;
	case 7:
		mySort(fnote);
		break;
	default:
		perror("switch error");
	}
}

void saveFile(fNote *fnote)
{
	FILE *pFile = fopen("addressBook.txt", "wb");
	if (!pFile){
		perror("file open error");
		exit(1);
	}
	fwrite(fnote->arrNote, sizeof(Note)*(fnote->personNum), 1, pFile);//将整个结构体数组一次写入文件
	fclose(pFile);
}

void loadFile(fNote *fnote)
{
	FILE *pFile = fopen("addressBook.txt", "rb");
	if (!pFile){
		perror("file open error");
		exit(1);
	}
	for (int i = 0; fread(&(fnote->arrNote[i]), sizeof(Note), 1, pFile) == 1; i++){
		fnote->personNum++;
	}
	fclose(pFile);
}

int  main()
{
	int personSum = 0;//代表可以添加的联系人数
	printf("Please enter the number of people to add first:");
	scanf("%d", &personSum);

	fNote *fnote;
	fnote = (fNote *)malloc(sizeof(fNote) + personSum *sizeof(Note));
	if (fnote){
		fnote->personNum = 0;
		loadFile(fnote);
		fNote *tmp = realloc(fnote, sizeof(fNote) + (personSum + fnote->personNum)*sizeof(Note));//扩展fnote空间,加上文件中的联系人
		if (tmp){
			fnote = tmp;
			personSum += fnote->personNum;
		}
		int sel;
		do{
			menu();
			scanf("%d", &sel);
			system("cls");
			if (!sel){
				saveFile(fnote);//退出之前写入文件
				exit(EXIT_FAILURE);
			}
			else if (sel > 7 && sel < 0){
				printf("enter error!please try again:[0,7]");
			}
			else{
				branch(fnote, sel, personSum);
			}
		} while (1);
	}
	free(fnote);
	fnote = NULL;

	system("pause");
	return 0;
}

 

测试结果:在文件无内容时,运行程序,添加两个联系人(显示所有),然后退出(0)

 

 

查看文件内容:(以二进制格式写入,所以出现乱码)

再次运行程序:不添加任何联系人,直接显示所有(5)

 

 

文件存储成功,其他功能都测试成功,具体图可见c_静态存储1000人通讯录

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值