通讯录管理系统

        自己做的一个用文件实现的通讯录管理系统,有增、删、改、查、显示、排序、统计、退出七个功能,联系人有姓名、年龄、学号、性别、所在院校、所在班级、联系方式、家庭电话、家庭住址和邮箱十个信息。

       添加时和修改时有判断年龄是否符合、学号是否重复两个检验模块。删除和修改都是用一个临时文件保存不删除和不修改的联系人,然后把临时文件改为原来的名字。查找和显示遍历文件就好。排序有按学号升序和按学号降序两种方式,主要思想是将学号放入一个数组中,然后将数组排好序,再将学号排序到文件中。

        然后各种功能模块都进行了封装。写这个主要是为了记录自己的学习成果,如有不足之处,请指正,一起学习,一起进步。以下是代码,有六百多行。

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

#define head "姓名","年龄","学号","性别","学校","班级","联系电话","家庭电话","家庭地址","邮箱" 
#define print p->pName,p->pAge,p->pId,p->pSex,p->pSchool,p->pClass,p->pSelfPhone,p->pFamilyPhone,p->pAddress,p->pE_mail
#define scan &p->pName,&p->pAge,&p->pId,&p->pSex,&p->pSchool,&p->pClass,&p->pSelfPhone,&p->pFamilyPhone,&p->pAddress,&p->pE_mail
#define file "C:\\Users\\Lenovo\\Desktop\\Person.txt"
#define fileTemp "C:\\Users\\Lenovo\\Desktop\\temp.txt"
#define formatPrint "%s\t%d\t%ld\t%s\t%s\t%s\t%s\t\t%s\t\t%s\t\t%s\n" 
#define formatScan "%s\t%d\t%ld\t%s\t%s\t%s\t%s\t\t%s\t\t%s\t\t%s\n"
#define formatHead "%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\n"

struct Person;		//通讯录结构体 
void menu();		//菜单函数
void choose();		//选择函数
void add();			//添加联系人函数
void deleteFun();					//删除联系人函数
void deleteMenu();					//删除菜单函数
int deleteChoose();					//删除选择函数 
void deleteIdOrName(int select);	//选择学号或姓名删除联系人函数
void modify();						//修改联系人函数
void modifyMenu();					//修改菜单函数 
Person *modifyChoose(int select,FILE *fp,Person *p);	//修改选择函数
void modifyIdOrName(int select);			//选择学号或姓名修改联系人函数
void search();						//查找联系人函数
void searchIdOrName(int select);	//选择学号或姓名查询联系人函数
void show();		//显示联系人函数
void sort();						//排序联系人函数
void AscendingAndDescending(int select);		//升序和降序联系人函数
void insertion_sort(long array[],int lenth,int select);	//插入排序算法
void sum();		//统计联系人 
void quit();		//退出函数
void clear();		//清空控制台函数 
void open(FILE *fp);//文件打开失败函数
void close(FILE *fp);//文件关闭失败函数 
int isEmpty(FILE *fp,Person *p,long id,char name[10]);//判断联系人是否存在
int isAge();					//判断联系人年龄是否合适函数
int isId(FILE *fp,Person *p);	//判断联系人学号是否重复函数
void renameFile(FILE *fp,FILE *fpTemp,Person *p);		//关闭、删除、重命名文件 
void printFile(FILE *fp,Person *p,long id,char name[10]);	//打印出查询的结果 

struct Person{//通讯录结构体 
	char pName[10];			//姓名 
	char pSex[3];			//性别 
	char pAddress[30];		//家庭地址 
	char pSchool[30];		//所在院校 
	char pClass[30];		//所在班级 
	char pSelfPhone[20];	//联系方式 
	char pFamilyPhone[20];	//家庭电话 
	char pE_mail[20]; 		//邮箱 
	long pId;				//学号 
	int pAge;				//年龄
	int pFlag;				//判断标志 
}; 

int main(void){//主函数 
	system("color f1");			//修改窗口的背景颜色和字体颜色 
	system("mode con cols=130");//修改窗口大小
	
	while(true){	//用一个死循环 
		menu();		//调用菜单命令 
		choose(); 	//调用选择命令 
	}
	return 0;
}

void menu(){//菜单函数 
	printf("\t\t	*********************★通讯录管理系统★******************\n");
	printf("\t\t	*			1:添加联系人			*\n");
	printf("\t\t	*			2:删除联系人			*\n");
	printf("\t\t	*			3:修改联系人			*\n");
	printf("\t\t	*			4:查询联系人			*\n");
	printf("\t\t	*			5:查看联系人			*\n");
	printf("\t\t	*			6:排序联系人			*\n");
	printf("\t\t	*			7:统计联系人			*\n");
	printf("\t\t	*			8:退出通讯录		   	*\n");
	printf("\t\t	*********************************************************\n");
	printf("请输入你的选择:");
}

void choose(){//选择函数 
	int select;
	scanf("%d",&select);
	switch(select){
		case 1: add();break;//新建联系人 
		case 2: deleteFun();break;//删除联系人 
		case 3: modify();break;//修改联系人 
		case 4: search();break;//查找联系人 
		case 5: show();break;//显示联系人 
		case 6: sort();break;//排序联系人 
		case 7: sum();break;//统计联系人 
		case 8: quit();break;//退出通讯录系统 
		default: printf("输入有误\n");clear();
	} 
}

void add(){//添加联系人函数 
	
	FILE *fp=fopen(file,"ab+");//用追加二进制的方式读写文件 
	open(fp);//调用判断文件是否会打开失败函数 
	
	//因为后面要判断学号是否重复
	//所以Person中的name、age和id会被覆盖
	//所以用临时变量储存 
	char name[10];
	int age;
	long id;
	Person *p = (Person*)malloc(sizeof(Person));//动态分配内存 
	printf("请输入姓名:"); 	scanf("%s",name);
	printf("请输入年龄:");		age = isAge();//判断联系人年龄是否合适函数 
	printf("请输入学号:");		id = isId(fp,p);//判断联系人学号是否重复函数 
	
	strcpy(p->pName,name);
	p->pAge=age;
	p->pId=id;
	printf("请输入性别:"); 	scanf("%s",&p->pSex);
	printf("请输入学校:"); 	scanf("%s",&p->pSchool);
	printf("请输入班级;"); 	scanf("%s",&p->pClass);
	printf("请输入联系电话:"); scanf("%s",&p->pSelfPhone);
	printf("请输入家庭电话:"); scanf("%s",&p->pFamilyPhone);
	printf("请输入家庭地址:"); scanf("%s",&p->pAddress);
	printf("请输入邮箱:"); 	scanf("%s",&p->pE_mail);
	
	fseek(fp,0L,SEEK_END);//将文件指针定位到文件末尾 
	fprintf(fp,formatPrint,print);//输入文件 
	
	close(fp);//关闭文件 
	free(p);//释放Person指针 
	printf("新建成功!\n");
	clear();//清空控制台函数 
}

void deleteFun(){//删除联系人函数
	int flag=1;
	while(flag!=0){
		deleteMenu();//调用删除菜单函数 
		flag = deleteChoose();//调用删除选择函数,返回值是0则结束 
	}
	clear();
}

void deleteMenu(){//删除菜单函数 
	system("cls");
	printf("\t\t	************************★删除信息★*********************\n");
	printf("\t\t	*	           1.输入被删除人的学号			*\n");
	printf("\t\t	*		   2.输入被删除人的姓名			*\n");
	printf("\t\t	*		   3.返回上一级菜单			*\n");
	printf("\t\t	*********************************************************\n");
	printf("请输入你的选择:");
}

int deleteChoose(){//删除选择函数 
	int select,flag=1;
	scanf("%d",&select);
	switch(select){
		case 1: 
		case 2: deleteIdOrName(select);flag=1;break;//调用按学号或姓名删除联系人函数 
		case 3: flag = 0;break;
		default: printf("输入有误!\n");clear();
	}
	return flag;
}

void deleteIdOrName(int select){//选择学号删除联系人函数
	FILE *fp=fopen(file,"ab+");
	FILE *fpTemp=fopen(fileTemp,"wb");//一个临时文件 
	open(fpTemp);
	open(fp);
	Person *p=(Person*)malloc(sizeof(Person)); 
	
	long id;
	char name[10];	
	if(select==1){
		printf("请输入被删除人的学号:");
		scanf("%d",&id);
	}else {
		printf("请输入被删除人的姓名:");
		scanf("%s",name);
	}
	
	int flag = isEmpty(fp,p,id,name);//调用判断联系人是否存在函数 
	if(flag==0){
		printf("该联系人不存在!\n");
		clear();
		return;
	}
	
	printFile(fp,p,id,name);
	
	printf("是否确认删除?\n");
	printf("1.是	2.否\n");
	printf("请输入你的选择:");
	while(true){
		scanf("%d",&flag);
		if(flag==1){
			break;
		}else if(flag==2){
			return;
		}else{
			printf("输入有误,请重新输入:");
		}
	}
	
	fseek(fp,0L,SEEK_SET);//将文件指针定位到开头 
	while(!feof(fp)){
		fscanf(fp,formatScan,scan);
		if(select==1&&p->pId!=id){//select==1是按学号删除,如果匹配到相同,
                                          //则不存到临时文件中,达到删除联系人的目的 
			fprintf(fpTemp,formatPrint,print);
		}
		
		if(select==2&&strcmp(p->pName,name)!=0){//select==2是按姓名删除 
			fprintf(fpTemp,formatPrint,print);
		}
	}
	
	renameFile(fp,fpTemp,p);
	printf("删除成功!\n");
	clear();
}

void modify(){//修改联系人函数
	system("cls");
	
	int flag=1;
	while(flag!=0){
		printf("\t\t	************************★修改信息★*********************\n");
		printf("\t\t	*		    1.输入被修改人的学号		*\n");
		printf("\t\t	*		    2.输入被修改人的姓名		*\n");
		printf("\t\t	*		    3.返回上一级菜单      		*\n");
		printf("\t\t	*********************************************************\n");
		printf("请输入你的选择:");
		int select;
		scanf("%d",&select);
		switch(select){
			case 1: 
			case 2: modifyIdOrName(select);flag=1;break;
			case 3: flag=0;break;
			default: printf("输入有误!\n");
		} 
	}
	clear();
}

void modifyMenu(){//修改菜单函数 
	printf("\t\t	*********************************************************\n");
			printf("\t\t	*			1:修改姓名			*\n");
			printf("\t\t	*			2:修改年龄			*\n");
			printf("\t\t	*			3:修改学号			*\n");
			printf("\t\t	*			4:修改性别			*\n");
			printf("\t\t	*			5:修改学校			*\n");
			printf("\t\t	*			6:修改班级			*\n");
			printf("\t\t	*			7:修改联系电话			*\n");
			printf("\t\t	*			8:修改家庭电话			*\n");
			printf("\t\t	*			9:修改家庭地址			*\n");
			printf("\t\t	*			10:修改邮箱			*\n");
			printf("\t\t	*			11:全部修改			*\n");
			printf("\t\t	*			12:返回				*\n");
			printf("\t\t	*********************************************************\n");
			printf("请输入你的选择:");
}

Person *modifyChoose(int select,FILE *fp,Person *p){//修改选择函数 
	char name[10];
	int age;
	long id;
	switch(select){
		case 1: printf("请输入新的姓名:");		scanf("%s",p->pName);		break;
		case 2: printf("请输入新的年龄:");		age = isAge();p->pAge = age;break;
		case 3: printf("请输入新的学号:");		id = isId(fp,p);p->pId = id;break;
		case 4: printf("请输入新的性别:");		scanf("%s",p->pSex);		break;
		case 5: printf("请输入新的学校:");		scanf("%s",p->pSchool);		break;
		case 6: printf("请输入新的班级:");		scanf("%s",p->pClass);		break;
		case 7: printf("请输入新的联系电话:");	scanf("%s",p->pSelfPhone);	break;
		case 8: printf("请输入新的家庭电话:");	scanf("%s",p->pFamilyPhone);break;
		case 9: printf("请输入新的家庭地址:");	scanf("%s",p->pAddress);	break;
		case 10: printf("请输入新的邮箱:");	scanf("%s",p->pE_mail);		break;
		case 11: {
				printf("请输入新的姓名:");		scanf("%s",name);
				printf("请输入新的年龄:");		age = isAge();
				printf("请输入新的学号:");		id = isId(fp,p);
				printf("请输入新的性别:");		scanf("%s",p->pSex);
				printf("请输入新的学校:");		scanf("%s",p->pSchool);
				printf("请输入新的班级:");		scanf("%s",p->pClass);
				printf("请输入新的联系电话:");	scanf("%s",p->pSelfPhone);
				printf("请输入新的家庭电话:");	scanf("%s",p->pFamilyPhone);
				printf("请输入新的家庭地址:");	scanf("%s",p->pAddress);
				printf("请输入新的邮箱:");		scanf("%s",p->pE_mail);
				strcpy(p->pName,name);
				p->pAge = age;
				p->pId = id;
				}break;
		default: printf("输入错误,请重新输入:");
		}
		
	printf("是否确认修改?\n");
	printf("1.是	2.否\n");
	printf("请输入你的选择:");
	while(true){
		scanf("%d",&p->pFlag);
		if(p->pFlag==1||p->pFlag==2){
			break;
		}else{
			printf("输入错误,请重新输入:");
		}
	}
	return p;
}

void modifyIdOrName(int select){//选择学号或姓名修改联系人函数
	FILE *fp=fopen(file,"ab+");
	FILE *fpTemp=fopen(fileTemp,"wb");
	open(fpTemp);
	open(fp);
	Person *p=(Person*)malloc(sizeof(Person)); 
	
	long id;
	char name[10];	
	if(select==1){
		printf("请输入被修改人的学号:");
		scanf("%ld",&id);
	}else {
		printf("请输入被修改人的姓名:");
		scanf("%s",name);
	}
	
	int flag = isEmpty(fp,p,id,name);
	if(flag==0){
		printf("该联系人不存在!\n");
		clear();
		return;
	}
	
	printFile(fp,p,id,name);
	
	modifyMenu();//调用修改菜单函数 
	
	while(true){
		scanf("%d",&select);
		if(select>=1&&select<=12){
			if(select==12){
				clear();
				return;
			}
			break;
		}else{
			printf("输入有误,请重新输入:");
		}
	}

	fseek(fp,0L,SEEK_SET);
	while(!feof(fp)){
		fscanf(fp,formatScan,scan);
		if(p->pId==id||strcmp(p->pName,name)==0){
			p = modifyChoose(select,fp,p);
			if(p->pFlag==2){//如果flag=2,则不修改联系人,并结束函数 
				return;
			}
			//将修改后的信息写入临时文件 
			fprintf(fpTemp,formatPrint,print);
		}else{
			fprintf(fpTemp,formatPrint,print);
		}
	}
	
	renameFile(fp,fpTemp,p);
	printf("修改成功!\n");
	clear();
}

void search(){//查询联系人函数 
	int select,flag=1;
	while(flag!=0){
		system("cls");
		printf("\t\t	**********************★查询信息★***********************\n");
		printf("\t\t	*		 1.输入被查询人的学号			*\n");
		printf("\t\t	*		 2.输入被查询人的姓名			*\n");
		printf("\t\t	*		 3.返回上一级菜单   			*\n");
		printf("\t\t	*********************************************************\n");
		printf("请输入你的选择:");
		scanf("%d",&select);
		switch(select){
			case 1: 
			case 2: searchIdOrName(select);flag=1;break;
			case 3: flag=0;break;
			default: printf("输入有误,请重新输入:");
		}
	}
	clear();
}

void searchIdOrName(int select){//选择学号或姓名修改联系人函数
	FILE *fp = fopen(file,"r");
	open(fp);
	Person *p = (Person*)malloc(sizeof(Person));
	
	long id=0;
	char name[10]="";	
	if(select==1){
		printf("请输入被查询人的学号:");
		scanf("%ld",&id);
	}else {
		printf("请输入被查询人的姓名:");
		scanf("%s",name);
	}
	
	int flag = isEmpty(fp,p,id,name);
	if(flag==0){
		printf("该联系人不存在!\n");
		clear();
		return;
	}
	
	printFile(fp,p,id,name);
	
	close(fp);
	free(p);
	clear();
} 

void show(){//显示联系人函数
	FILE *fp=fopen(file,"r");
	open(fp);
	
	if(fp==NULL){
		perror("文件不存在\n");
		close(fp);
	}
	
	char ch = fgetc(fp);
	if(ch==EOF){
		printf("文件为空!\n");
		return;
	}
	
	printf("所有联系人信息如下:\n");
	printf(formatHead,head);
	
	fseek(fp,0L,SEEK_SET);
	char chTemp[1024];//一行一行读数据 
	while(!feof(fp)){
		printf("%s",chTemp);
		fgets(chTemp,1024,fp);
	}
	close(fp);
	clear();
}

void sort(){//排序联系人函数
	system("cls");
	
	int select,flag=1;
	while(flag!=0){
		printf("\t\t	*************************★排序信息★********************\n");
		printf("\t\t	*			1.按学号升序			*\n");
		printf("\t\t	*			2.按学号降序			*\n");
		printf("\t\t	*			3.返回上一级   			*\n");
		printf("\t\t	*********************************************************\n");
		printf("请输入你的选择:");
		scanf("%d",&select);
		switch(select){
			case 1: 
			case 2: AscendingAndDescending(select);flag=1;break;
			case 3: flag=0;break;
			default: printf("输入有误,请重新输入:");
		}
	} 
	clear();
}

void AscendingAndDescending(int select){//升序和降序联系人函数
	FILE *fp = fopen(file,"ab+");
	FILE *fpTemp = fopen(fileTemp,"wb");
	Person *p = (Person*)malloc(sizeof(Person));
	
	int lenth=0;
	while(!feof(fp)){//得到文件的行数,即联系人的数量 
		fscanf(fp,formatScan,scan);
		lenth++;
	}
	
	fseek(fp,0L,SEEK_SET);
	int count=0;
	long array[lenth];
	while(!feof(fp)){//将所有id号都放到数组中 
		fscanf(fp,formatScan,scan);
		array[count]=p->pId;
		count++;
	}
	
	//然后将数组进行排序 
	if(select==1){//升序 
		insertion_sort(array,lenth,select);
	}else{//降序 
		insertion_sort(array,lenth,select);
	}
	
	//然后将数组的编号和id匹配,相同则放入文件中 
	count=0;
	while(count<lenth){
		fseek(fp,0L,SEEK_SET);
		while(!feof(fp)){
			fscanf(fp,formatScan,scan);
			if(p->pId==array[count]){
				fprintf(fpTemp,formatPrint,print);
				count++;	
			}
		}
	}
	
	renameFile(fp,fpTemp,p);
	printf("排序成功!\n");
	clear();
}

void insertion_sort(long array[],int lenth,int select){//插数排序算法
	//升序 
	if(select==1){
		for(int i=1;i<lenth;i++){
			for(int j=i;j>0;j--){//从第二个跟第一个开始比 
				if(array[j]<array[j-1]){
					//换值 
					long temp = array[j];
					array[j] = array[j-1];
					array[j-1] = temp;
				}
			}
		}
	}else{
		//降序
		 for(int i=lenth-1;i>=0;i--){
			for(int j=i;j<lenth;j++){//从倒数第二个跟倒数第一个开始比 
				if(array[j]<array[j+1]){
					//换值 
					long temp = array[j];
					array[j] = array[j+1];
					array[j+1] = temp;
				}
			}
		}
	}
}

void sum(){
	FILE *fp = fopen(file,"r");
	Person *p = (Person*)malloc(sizeof(Person));
	open(fp);
	int lenth=0;
	while(!feof(fp)){
		fscanf(fp,formatScan,scan);
		lenth++;
	}
	printf("总共有%d个联系人\n",lenth);
	close(fp);
	free(p);
	clear();
}

void quit(){//退出函数
	printf("欢迎下次使用!\n");
	exit(0); 
}

void open(FILE *fp){//文件打开失败函数 
	if(fp==NULL){//若文件不存在,则给提示并关闭文件和退出系统 
		perror("文件不存在\n");
		close(fp);
	}
}

void close(FILE *fp){//文件关闭失败函数 
	int flag = fclose(fp);
	if(flag!=0){
		perror("文件不存在\n");
		exit(0);
	} 
}

void clear(){//清空控制台函数 
	system("pause");
	system("cls");
}

int isEmpty(FILE *fp,Person *p,long id,char name[10]){//判断联系人是否存在 
	int flag=0;
	while(!feof(fp)){
		fscanf(fp,"%s\t%d\t%ld\t%s\t%s\t%s\t%s\t\t%s\t\t%s\t\t%s\n",scan);
		if(p->pId==id||strcmp(p->pName,name)==0){
			flag=1;
		}
	}
	return flag;
}

int isAge(){//判断联系人年龄是否合适 
	int age;
	while(true){
		scanf("%d",&age);
		if(age<0||age>120){
			printf("输入的年龄有误,请重新输入:");
		}else{
			break;
		}
	}
	return age;
}

int isId(FILE *fp,Person *p){//判断联系人学号是否重复 
	int id;
	int flag=1;
	while(flag!=0){
		scanf("%ld",&id);
		fseek(fp,0L,SEEK_SET);
		while(!feof(fp)){
			fscanf(fp,"%s\t%d\t%ld\t%s\t%s\t%s\t%s\t\t%s\t\t%s\t\t%s\n",scan);
			if(id==p->pId){
				printf("学号已重复,请重新输入:");
				flag=1; 
				break;
			}
			flag=0;
		}
	}
	return id;
}

void renameFile(FILE *fp,FILE *fpTemp,Person *p){//关闭、删除、重命名文件 
	close(fp);
	close(fpTemp);
	free(p);
	remove(file);//删除文件 
	rename(fileTemp,file);//将临时文件名改为原名 
}

void printFile(FILE *fp,Person *p,long id,char name[10]){//打印出查询的结果 
	fseek(fp,0L,SEEK_SET);//将文件指针定位到文件开头 
	while(!feof(fp)){
		fscanf(fp,formatScan,scan);//读取文件,知道文件末尾 
		if(p->pId==id||strcmp(p->pName,name)==0){//判断到相同则输出 
			printf("该联系人信息如下:\n");
			printf(formatHead,head);//打印表头 
			printf(formatPrint,print);//打印内容 
			break; 
		}
	}
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值