⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 address.c

📁 用C语言实现的通讯录管理
💻 C
字号:
#include <string.h>
#include <stdio.h>
#include <malloc.h>
#include <stdlib.h>
#include <conio.h>

struct address
{
	char name[20];
	char tel[20];
	char email[30];
	char relations[15];
	struct address *next;
};/*通信录的结构体*/
#define LEN sizeof(struct address)
int total_file_person=0;/*从文件读入人员数量*/
int total_list_person=0;/*新创建链表中人员数量*/

struct address *creat_address(void);/*创建并初始化通信录文件*/
struct address *add_address(struct address *head);/*添加记录*/
void show_relation(struct address *head,char *relat);/*按关系显示*/
void show_address(struct address *head);/*显示整个通信录*/
void search_address(struct address *head);/*查询记录*/
struct address *del_address(struct address *head);/*删除记录*/
struct address *revise_address(struct address *head);/*按姓名更新记录*/
void chang_point(struct address *p1,struct address *p2);/*将p2的内容复制给p1*/
struct address *order_address(struct address *head);/*通信录排序*/
void save_address(struct address *head);/*存储文件*/
struct address *load_address(struct address *head);/*读入记录*/
void release(struct address *head);/*释放内存*/
void show_menu(void);/*显示菜单*/

void main()
{
	struct address *head=NULL;
	char choice='\0',choose='\0';
	do
	{
		system("cls");
		show_menu();
		choice=getche();
		printf("\n");
		getchar();
		switch(choice)
		{   case '0':head=creat_address();break;
			case '1':head=add_address(head);break;
			case '2':show_address(head);break;
			case '3':search_address(head);break;
			case '4':head=del_address(head);break;
			case '5':head=revise_address(head);break;
			case '6':head=order_address(head);break;
			case '7':save_address(head);break;
			case '8':head=load_address(head);break;
			case '9':break;
			default:printf("请输入数字(0-9)!\n");
		}
		if(choice=='9') 
		{
			printf("是否保存文件(Y or N)?");
			choose=getche();
			if (choose=='Y' || choose=='y')
			{
				save_address(head);
			}
			release(head);
			printf("\n现在退出程序!\n");
			break;
		}
		printf("\n按空格键后继续选择其他操作!");
		getche();
	}while(1);
}


struct address *creat_address(void)/*创建并初始化通信录文件*/
{
	int R,F,W,C,choice;
	struct address *head;
	struct address *p1,*p2;
	p1=p2=(struct address *)malloc(LEN);
	head=NULL;
	printf("提示:输入'#'时停止!\n");
	printf("请输入姓名:");
	scanf("%s",p1->name);
	while(p1->name[0]!='#')
	{
		++total_list_person;
		if(total_list_person==1) head=p1;
		else p2->next=p1;
		p2=p1;
		getchar();
		printf("请输入电话:");
		scanf("%s",p1->tel);
		getchar();
		printf("请输入Email:");
		scanf("%s",p1->email);
		getchar();
		printf("请输入指定关系:(Relative,Friend,Workmate 或 Classmate):");
		scanf("%s",p1->relations);
		getchar();
		R=strcmp(p1->relations,"Relative");
		F=strcmp(p1->relations,"Friend");
		W=strcmp(p1->relations,"Workmate");
		C=strcmp(p1->relations,"Classmate");
		choice=R&&F&&W&&C;
		while(choice)/*判断是否属于四种指定关系之一*/
		{
			printf("只能从四种关系中选择一种输入!\n");
			printf("请重新输入指定关系:(Relative,Friend,Workmate 或 Classmate):\n");
			scanf("%s",p1->relations);
			R=strcmp(p1->relations,"Relative");
			F=strcmp(p1->relations,"Friend");
			W=strcmp(p1->relations,"Workmate");
			C=strcmp(p1->relations,"Classmate");
			choice=R&&F&&W&&C;
		}

		getchar();
		p1=(struct address *)malloc(LEN); 
		printf("请输入姓名:");
		scanf("%s",p1->name);
	}
	p2->next=NULL;
	return(head);
}


struct address *add_address(struct address *head)/*添加记录*/
{
	struct address *p2;
	struct address *p1=(struct address *)malloc(LEN);
	int R,F,W,C,choice;
	printf("提示:输入'#'时停止!\n");
	printf("请输入姓名:");
	scanf("%s",p1->name);
	getchar();
	while(p1->name[0]!='#')
	{
		printf("请输入电话:");
		scanf("%s",p1->tel);
		getchar();
		printf("请输入Email:");
		scanf("%s",p1->email);
		getchar();
		printf("请输入指定关系:(Relative,Friend,Workmate 或 Classmate):");
		scanf("%s",p1->relations);

		R=strcmp(p1->relations,"Relative");
		F=strcmp(p1->relations,"Friend");
		W=strcmp(p1->relations,"Workmate");
		C=strcmp(p1->relations,"Classmate");
		choice=R&&F&&W&&C;
		while(choice)/*判断是否属于四种指定关系之一*/
		{
			printf("只能从四种关系中选择一种输入!\n");
			printf("请重新输入指定关系:(Relative,Friend,Workmate 或 Classmate):\n");
			scanf("%s",p1->relations);
			R=strcmp(p1->relations,"Relative");
			F=strcmp(p1->relations,"Friend");
			W=strcmp(p1->relations,"Workmate");
			C=strcmp(p1->relations,"Classmate");
			choice=R&&F&&W&&C;
		}
		getchar();
		if(head==NULL) head=p1;
		else
		{
			p2=head;
			while(p2->next!=NULL)	p2=p2->next;
			p2->next=p1;
			p1->next=NULL;
		}
		++total_list_person;
		p1=(struct address *)malloc(LEN); 
		printf("\n请输入姓名:");
		scanf("%s",p1->name);
	}
return(head);
}


void show_relation(struct address *head,char *relat)/*按关系显示*/
{
	struct address *p=head;/*使p指向第一个节点*/
	int total_relation=0;
	if(head==NULL) {printf("这是一个空记录!\n");goto END;}/*判断链表是否为空*/
	if(!strcmp(p->relations,relat)) 
	{
		printf("%s    %s    %s     %s\n",p->name,p->tel,p->email,p->relations);
		++total_relation;
	}
	while(p->next!=NULL)
	{
		 p=p->next;/*p后移一个节点*/
		 if(!strcmp(p->relations,relat)) printf("%s     %s     %s     %s\n",p->name,p->tel,p->email,p->relations);
		 ++total_relation;
	 }
	if(p->next==NULL&&total_relation==0) printf("没有此指定关系的通信录\n");
	END:NULL;
}


void show_address(struct address *head)/*显示整个通信录*/
{
	int choice;
	int chose;
	struct address *p;
	p=head;
	printf("请输入选择数字:\n");
	printf("1---显示所有记录\n");
	printf("2---显示指定关系的记录\n");
	scanf("%d",&choice);
	FIRST:NULL;
	switch(choice)
	{
		case 1:
		{	if(head!=NULL)
			{	printf("总共有%d条记录:\n",total_list_person);
				do 
				{
					printf("%s     %s     %s     %s\n",p->name,p->tel,p->email,p->relations);
					p=p->next;
			 
				}while(p!=NULL);
			}
			else printf("此通信录是空的!\n");
				 break;
		}
		case 2:
			printf("1---显示所有的亲戚(Relative)\n");
			printf("2---显示所有的朋友(Friend)\n");
			printf("3---显示所有的同事(Workmate)\n");
			printf("4---显示所有的同学(Classmate)\n");
			scanf("%d",&chose);
			switch(chose)
			{
				case 1:show_relation(head,"Relative");break;
				case 2:show_relation(head,"Friend");break;
				case 3:show_relation(head,"Workmate");break;
				case 4:show_relation(head,"Classmate");break;
	   		}
			break;
		default:goto FIRST;break;
	}
}


void search_address(struct address *head)/*查询记录*/
{
	char *name[20];
	struct address *p=head;/*使p指向第一个节点*/
	if(head==NULL) {printf("这是一个空通信录!\n");goto END;}/*判断链表是否为空*/
	printf("请输入所查询人员的姓名:");
	scanf("%s",name);
	getchar();
	while(strcmp(p->name,name))/*两者相等时值为0*/
		{
			if(p->next==NULL) 
			{	printf("没有找到%s!\n",name);
				goto END;
			}
			else  p=p->next;/*p后移一个节点*/
		}

	printf("%s     %s     %s     %s\n",p->name,p->tel,p->email,p->relations);
	END:NULL;
}


struct address *del_address(struct address *head)/*删除记录*/
{
	struct address *p1,*p2;
	int choice;
	//system("cls");
	printf("请输入所要删除的选项:\n");
	printf("1---删除指定人员的记录\n");
	printf("2---删除所有记录 \n");
	scanf("%d",&choice);
	getchar();
	switch(choice)
	{
		case 1:
		{
			char name[20];
			printf("请输入所要删除人员的姓名:");
			scanf("%s",name);
			if(head==NULL)/*判断链表是否为空*/
			{	printf("这是一个空通信录!\n");
				goto END;
			}
			p1=head;
			while(strcmp(p1->name,name)&&p1->next!=NULL)/*p1不是所要找的节点*/
			{
				p2=p1;
				p1=p1->next;
			}
			if(!strcmp(p1->name,name))/*找到了*/
			{	if(p1==head) 	head=p1->next;/*若p1指向首节点,则把第二个节点地址赋给head*/
				else p2->next=p1->next;
				printf("%s的记录已经被删除!\n",name);
				--total_list_person;
			}
			else printf("没有找到%s!\n",name);
			END:NULL;
			break;
		}
		case 2:
			head=NULL;
			//head->next=NULL;
			break;
	}
	return(head);
}


struct address *revise_address(struct address *head)/*按姓名更新记录*/
{
	int R,F,W,C,choice;
	char name[20];
	struct address *p=head;/*使p指向第一个节点*/
	printf("请输入需要修改的姓名:");
	scanf("%s",name);
	getchar();
	if(head==NULL) {printf("这是一个空记录!\n");goto END;}/*判断链表是否为空*/
	while(strcmp(p->name,name))/*两者相等时值为0*/
	{
		if(p->next==NULL) 
		{	printf("没有找到%s!\n",name);
			goto END;
		}
		else  p=p->next;/*p后移一个节点*/
	}

	printf("\n请输入修改后的姓名:");
	scanf("%s",p->name);
	getchar();
	printf("请输入修改后的电话:");
	scanf("%s",p->tel);
	getchar();
	printf("请输入修改后的Email:");
	scanf("%s",p->email);
	getchar();
	printf("请输入指定关系:(Relative,Friend,Workmate 或 Classmate):");
	scanf("%s",p->relations);
	R=strcmp(p->relations,"Relative");
	F=strcmp(p->relations,"Friend");
	W=strcmp(p->relations,"Workmate");
	C=strcmp(p->relations,"Classmate");
	choice=R&&F&&W&&C;
	while(choice)/*判断是否属于四种指定关系之一*/
	{
		printf("只能从四种关系中选择一种输入!\n");
		printf("请重新输入指定关系:(Relative,Friend,Workmate 或 Classmate):");
		scanf("%s",p->relations);
		R=strcmp(p->relations,"Relative");
		F=strcmp(p->relations,"Friend");
		W=strcmp(p->relations,"Workmate");
		C=strcmp(p->relations,"Classmate");
		choice=R&&F&&W&&C;
	}
	END:return(head);
}

void chang_point(struct address *p1,struct address *p2)/*将p2的内容复制给p1*/
{
	strcpy(p1->name,p2->name);strcpy(p1->tel,p2->tel);strcpy(p1->email,p2->email);strcpy(p1->relations,p2->relations);
}



struct address *order_address(struct address *head)/*通信录排序*/
{
	struct address *p1=head,*p2=head;/*使p1,p2指向第一个节点*/
	struct address *p3=(struct address *)malloc(LEN);
	int i,j;
	printf("现在开始排序!\n");//test
	if(head==NULL) {printf("这是一个空记录!\n");goto END;}/*空链表不用排序*/
	//if(head->next==NULL) goto END;/*单节点的链表不用排序*/
	p1=head->next;/*多节点链表排序*/
	for(i=0;i<total_list_person-1;i++)
   	{
		for(j=0;j<total_list_person-1-i;j++)
			{
				if(strcmp(p1->name,p2->name)<0)
				{
					chang_point(p3,p2);
					chang_point(p2,p1);
					chang_point(p1,p3);
				}
	
				p2=p1;
				p1=p1->next;
			}
		p1=head->next;
		p2=head;
	}
	printf("排序完成,下面开始显示排序后的内容:\n");
	show_address(head);
	END:return(head);
}


void save_address(struct address *head)/*存储文件*/
{
	FILE *fp;
	struct address *p=head;
	char filepn[50];
	int choice;
	printf("\n\t请选择保存方式:\n");
	printf("\t1---保存在自定义文件中\n");
	printf("\t2---保存在缺省文件中\n");
	scanf("%d",&choice);
	if(choice==1)
	{	printf("请输入要保存的文件路径与文件名:");
		scanf("%s",filepn);
	}
	else
		strcpy(filepn,"c:\\Phonebook.txt");

	if((fp=fopen(filepn,"w"))==NULL)
	{
		printf("cannot open this file\n");
		exit(0);
	}
	else
	{
		while(p!=NULL)
		{
			fprintf(fp,"%s    %s    %s    %s\n",p->name,p->tel,p->email,p->relations);
			p=p->next;
		}
		printf("文件保存成功!\n");	
	}
	fclose(fp);
}


struct address *load_address(struct address *head)/*读入记录*/
{ 
	struct address *p3,*p4;
	char filepn[50];
	int choice;
	char choose;
	FILE *fp;
	total_list_person=0;
	if(head!=NULL)
	{	
		printf("读取文件前请先保存当前记录(Y:保存;N:放弃)\n");
		scanf("%s",&choose);
		if((choose=='Y')||(choose=='y')) 
		{	save_address(head);
		}
	}
	printf("\n\t请选择读取文件的方式:\n");
	printf("\t1---从自定义文件中读取\n");
	printf("\t2---从缺省文件中读取(c:\\Phonebook.txt)\n");
	scanf("%d",&choice);
	if(choice==1)
	{	printf("请输入所读取文件的路径与文件名:");
		scanf("%s",filepn);
	}
	else
	{	strcpy(filepn,"c:\\Phonebook.txt");
	}
	head=p4=(struct address *)malloc(LEN);
	p3=(struct address *)malloc(LEN);
	if((fp=fopen(filepn,"r"))==NULL)
	{	
		printf("\n不存在此文件,请重新创建通信录!\n");
		goto END;
	}
    else
	{	
		while(!feof(fp))
		{
			fscanf(fp,"%s    %s    %s    %s\n",p3->name,p3->tel,p3->email,p3->relations);
			++total_list_person;	
			p4->next=p3;
			p4=p4->next;
			p3=(struct address *)malloc(LEN);
		}
		p4->next=NULL;
		printf("从文件读取了%d个信息\n",total_list_person);
		
		fclose(fp);
		head=head->next;
		show_address(head);

	}	
	END:return(head);
}

void release(struct address *head)/*释放内存*/
{
	struct address *p1,*p2;
	p1=head->next;
	while(p1!=NULL)
	{
		p2=p1->next;
		free(p1);
		p1=p2;
	}
	printf("\n释放内存完毕,BYE!\n");
   
}



void show_menu(void)/*显示菜单*/
{
	printf("\n***************************************\n");
	printf("\n\t通信录管理菜单\n");
	printf("\n***************************************\n");
	printf("\t0---创建记录\n");
	printf("\t1---添加记录\n");
	printf("\t2---显示记录\n");
	printf("\t3---查询记录\n");
	printf("\t4---删除记录\n");
	printf("\t5---更新记录\n");
	printf("\t6---通信录排序\n");
	printf("\t7---保存记录\n");
	printf("\t8---读入记录\n");
	printf("\t9---退出\n");
	printf("***************************************\n\n");
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -