C-结构体+链表-实现“通讯录管理系统”

界面:基于控制台实现用户的输入和输出,主菜单界面,用 while语句实现不断执行直到用户自行选择退出。

程序流程:在main函数中实现主界面功能提示,通过调用函数,实现各个功能。使用结构体描述用户所具有的基本信息。

具体功能:

  1. 退出系统(操作人可根据需求按提示随时退出系统)
  2. 创建通讯录(包括姓名、工作单位、手机号码、电子邮箱)
  3. 查询通讯录(根据联系人姓名来查询信息)
  4. 修改通讯录(根据联系人的姓名找到要修改的联系人并进行修改)
  5. 删除通讯录(根据联系人姓名来删除对应联系人)
  6. 按姓名进行排序(根据联系人姓名对应的ASCII码值,按由小到大排序)
  7. 显示通讯录(可以把创建的联系人打印出来)

子函数划分:

a、创建通讯录联系人

b、查询联系人

c、修改联系人

d、删除联系人

e、对联系人按姓名排序

f、退出系统

g、显示联系人信息

h、为联系人动态开辟内存空间

部分界面展示:在这里插入图片描述

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <malloc.h>
#define LEN sizeof(struct linkman) //宏定义结构体的空间,为下面动态开辟空间做准备
int len;                           // 记录当前已经记录的人数


typedef struct linkman
{
	char username[20];    // 姓名
	char address[30];     // 工作单位
	char phone[20];       // 联系电话
	char email[30];       // 邮箱
	struct linkman *next; // 指针 指向下一个联系人
} linkman;

//  创建链表
struct linkman *create() {
	linkman * head_linkmanlist; 
	linkman *var1, *var2; // 初始化一个当前链表的指针
	char name[20]; // 姓名输入在20个长度之内
	len = 0;
	var1 = (linkman *)malloc(LEN);
	var2 = var1;
	printf("请录入当前需要录入的人员信息!\n姓名输入n时代表结束创建\n\n");
	printf("请输入联系人姓名:");
	gets(name);
	if (strcmp(name, "n") != 0)
	{
		strcpy(var1->username, name);
		printf("请输入联系人工作单位:"); gets(var1->address);
		printf("请输入联系人联系电话:"); gets(var1->phone);
		printf("请输入联系人电子邮箱:"); gets(var1->email);
		head_linkmanlist = NULL;
		while (1)
		{
			len = len + 1;  //记录通讯录个数
			if (len == 1)
			{

				head_linkmanlist = var1;
			}
			else
			{

				var2->next = var1;
			}
			var2 = var1;
			printf("请输入姓名:");
			gets(name);
			if (strcmp(name, "n") == 0)
			{
				break;
			}
			else
			{
				var1 = (linkman *)malloc(LEN);
				strcpy(var1->username, name);
				printf("请输入联系人工作单位:"); gets(var1->address);
				printf("请输入联系人联系电话:"); gets(var1->phone);
				printf("请输入联系人电子邮箱:"); gets(var1->email);
			}
		}
		var2->next = NULL;
		return head_linkmanlist;
	}
	else
		return head_linkmanlist;
};


//修改
void changeLinkman(linkman *head_linkman)
{
	linkman *p1, *p2;
	char name[20];
	int nM;
	if (head_linkman == NULL)
	{
		printf("您操作的通讯录此时为空,不能进行修改操作!");

	}
	p1 = head_linkman;
	nM = 0;
	if (p1 != NULL)
	{

		printf("请输入要修改的联系人的姓名:");
		gets(name);
		while (strcmp(p1->username, name) != 0 && p1->next != NULL)
		{
			p2 = p1;
			p1 = p1->next;
		}
		if (strcmp(p1->username, name) == 0)
		{
			nM++;
			int nCase;
			printf("==========================你要修改的的联系人是=============================\n\n");
			printf("姓名:%s\t学校名称:%s\t联系电话:%s\t电子邮箱:%s\t\n\n", p1->username, p1->address, p1->phone, p1->email);
			printf("============================================================================\n\n");
			switch (1)
			{
			case 1:
			{
				char changename[20];
				printf("请输入新的姓名:");
				gets(name);
				strcpy(p1->username, name);
				printf("姓名已修改为:%s\n\n", p1->username);
			}
			case 2:
			{
				char changedAddress[20];
				printf("请输入新的工作单位:");
				gets(changedAddress);
				strcpy(p1->address, changedAddress);
				printf("工作单位已修改为:%s\n\n", p1->address);
			}
			case 3:
			{
				char changedPhone[20];
				printf("请输入新的电话号码:");
				gets(changedPhone);
				strcpy(p1->phone, changedPhone);
				printf("电话号码已修改为:%s\n\n", p1->phone);
			}
			case 4:
			{
				char changedEmail[20];
				printf("请输入新的电子邮箱:");
				gets(changedEmail);
				strcpy(p1->email, changedEmail);
				printf("电子邮箱已修改为:%s\n\n", p1->email);
			}break;
			default:
				printf("您输入的选项有误,请查证后重新操作!!\n");
				break;
			}
		}
		
		if (nM == 0)
		{
			printf("此人未录入到通讯录中,不能进行修改操作!\n");
		}
	}
}



// 显示
void show(linkman * head_linkman)
{
	linkman *p;
	p = head_linkman;
	if (p != NULL)
	{

		printf("本通讯录系统现在记录共有%d人:\n", len);
		if (p != NULL)
		{
			do
			{
				printf("姓名:%s\n学校名称:%s\n联系电话:%s\n电子邮箱:%s\n\n", p->username, p->address, p->phone, p->email);
				p = p->next;
			} while (p != NULL);
		}
	}
	else
	{
		printf("通讯录为空!\n");
	}
}

//删除
linkman *deleNode(linkman *head_linkman)
{
	
	linkman *v1, *v2;
	char name[20];
	if (head_linkman == NULL)
	{
		printf("您操作的通讯录此时为空,不能进行删除操作!");
	}
	printf("请输入要删除的联系人的姓名:");
	gets(name);

	for (v2 = v1 = head_linkman; v1 != NULL;)
	{
		if (strcmp(v1->username, name) == 0)
		{
			if (strcmp(head_linkman->username,name) == 0)//对头指针特殊处理
			{
				v1 = head_linkman;
				head_linkman = head_linkman->next;
				free(v1);
				printf("该联系人已成功删除!\n");
				v2 = v1 = head_linkman;
				len--;
				return head_linkman;
			}
			else
			{
				v2->next = v1->next;
				free(v1);
				v1 = v2->next;
				printf("该联系人已成功删除!\n");
				len--;
				return head_linkman;
			}
		}
		else
		{
			v2 = v1;
			v1 = v1->next;
		}

	}
	printf("你要删除的联系人不存在\n\n");
	return head_linkman;

}
//查询
void serachLink(linkman *head_linkman)
{
	linkman *p1, *p2;
	char name[20];
	int nM;
	if (head_linkman == NULL)
	{
		printf("您操作的通讯录此时为空,不能进行查询操作!");

	}
	p1 = head_linkman;
	nM = 0;
	if (p1 != NULL)
	{

		printf("请输入要查询的联系人的姓名:");
		gets(name);
		while (strcmp(p1->username, name) != 0 && p1->next != NULL)
		{

			p1 = p1->next;
		}
		if (strcmp(p1->username, name) == 0)
		{
			nM++;
			printf("--------------------------你查找的联系人是----------------------------\n\n");
			printf("姓名:%s\t学校名称:%s\t联系电话:%s\t电子邮箱:%s\t\n", p1->username, p1->address, p1->phone, p1->email);
		}
		
		if (nM == 0)
		{
			printf("此人未录入通讯录!\n");
		}
	}


}

//按姓名排序
linkman *paixu(linkman *head_linkman)
{
	linkman *p3;//临时变量,释放空间用
	linkman *p1, *p2;
	int i, j;
	typedef struct linkman_one
	{
		char username[20];    // 姓名
		char address[30];     // 工作单位
		char phone[20];       // 联系电话
		char email[30];       // 邮箱
	};
	struct linkman_one px[400];
	struct linkman_one temp;
	if (head_linkman == NULL)
	{
		printf("你操作的通讯录为空,不能进行排序!\n\n");
		return head_linkman;
	}
	p1 = head_linkman;
	for (i = 1, i <= len; p1 != NULL; i++)
	{
		strcpy(px[i].username, p1->username);
		strcpy(px[i].address, p1->address);
		strcpy(px[i].phone, p1->phone);
		strcpy(px[i].email, p1->email);
		p2 = p1;
		p1 = p1->next;
	}

	while (head_linkman != NULL)//释放链表内存
	{
		p3 = head_linkman;
		head_linkman = head_linkman->next;
		free(p3);
	}

	for (j = 1; j <= len; j++)//进行排序
	{
		for (i = j + 1; i <= len; i++)
		{
			if (strcmp(px[i].username, px[j].username) < 0)
			{
				temp = px[i];
				px[i] = px[j];
				px[j] = temp;
			}
		}
	}
	
	p1 = (linkman *)malloc(LEN);
	p2 = p1;
	strcpy(p1->username, px[1].username);
	strcpy(p1->address, px[1].address);
	strcpy(p1->phone, px[1].phone);
	strcpy(p1->email, px[1].email);

	head_linkman = p1;
	for (i = 2; i <= len; i++)
	{
		p1 = (linkman *)malloc(LEN);
		strcpy(p1->username, px[i].username);
		strcpy(p1->address, px[i].address);
		strcpy(p1->phone, px[i].phone);
		strcpy(p1->email, px[i].email);
		p2->next = p1;
		p2 = p1;

	}
	p2->next = NULL;
	printf("通讯录按姓名排序后为:\n\n");
	show(head_linkman);
	return head_linkman;

}

//菜单
void menu()
{

	
	printf("\t\t|--------------------通讯录管理系统—----------------|\n");
	printf("\t\t| [0] 退出系统                                      |\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|---------------------------------------------------|\n");
	printf("\t\t\t请输入功能选项(0-6):");

}

void main()
{

	struct linkman *pt = NULL;
	int n;// n为定义输入数字

	while (1)
	{
		menu();
		scanf("%d", &n);
		fflush(stdin);

		switch (n)
		{

		case 1:
		{
			pt = create();
			show(pt);

		} break;
		case 2:
		{
			serachLink(pt);
			

		} break;
		case 3:
		{
			changeLinkman(pt);
			show(pt);

		} break;
		case 4:
		{
			pt = deleNode(pt);
			show(pt);

		} break;
		case 5:
		{
			pt = paixu(pt);


		} break;
		case 6:
		{
			show(pt);

		} break;
		case 0:
			printf("谢谢使用,您已退出当前系统!\n\n");
			break;
		default:
			printf("您输入的选项有误,没有此功能!请查证后重新操作!!\n");
			break;
		}
		if (n == 0)
		{
			break;
		}
	}
}

本人实测代码可行。比较简单利用结构体和链表进行操作。如有不完善之处还请大家指正。

  • 11
    点赞
  • 52
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
一:需求分析 二:总设计 三:详细设计 四:调试与测试 五;测试结果 六:本次课程设计的心得会 七:附录 本程序设计亮点介绍(及)改进方面 1.在修改函数中,可以实现单条记录修改(运用switch) 2.查询函数中,能返回该函数继续查询(运用了递归) 3.使用变量少,仅通过变量i的递加和表示成员数的变量n就实现了数据结构之间的联 系 4.界面美观,使用方便 5.允许编号输入为字符 6.在显示函数上能够分屏显示(换页) 缺点 在输入数据时,未输完一个成员的所有信息不能退出输入 一:需求分析 A.需要实现的功能有:输入功能、输出功能、显示功能、查找功能、以及增加、删 除、修改功能。输入功能要求一次完成若干信息的输入;显示功能要能完成所有信息的 显示,并且自动分页;查找可以通过多种方式进行。 按需求的功能,应该设计出输入函数、输出函数、显示函数、查找函数、修改函数。另 需要一个标准界面。 B.数据存储问题 这个系统数据庞大复杂,需要需要适当应用数组,循环,结构,文件操作等基本 语句及稍有难度的语句。因此要求我们熟练掌握结构化程序设计的基本思路和方法,在 所掌握的基本知识和技能的基础上,进一步提高自学能力和查找资料的能力,解决一定 程度的复杂的结构化程序设计问题,加深对所学知识的理解与掌握,利用自己所学知识 解决实际问题的能力,为以后的程序开发打下基础。 二:总设计 主要结构图示 本程序由主函数和多个子函数组成,可执行多种数据管理的功能。具通过c语言中 结构数组来实现。主函数主为定义的结构,和一个switch函数,以提供多种程序 操作功能。 主要需运用到结构数组、文件、函数等内容知识。 子函数有六个,分别负责添加、显示、删除、查询、修改、保存的功能。通过变量i使结 构数组之间达成数据链表的功能,利用该方法主要考虑到成员中对于结构指针尚未 熟练掌握,而这种方法更加便捷易懂。 子函数功能介绍 1. 添加:输入成员信息,依次输入编号、姓名、QQ、电话号码、单位、电子邮箱、身 份。 2. 显示:以表格形式输出所有通讯记录 3. 删除:只需输入该成员姓名,便删除其所有记录 4. 查询:可选用姓名、电话、单位身份4种方式来查询 5. 修改:输入该成员姓名后,再依次输入更新信息完成修改 6. 保存:输入文件名(带后缀)后保存。C-free中会默认以txt文件保存至c- free standard/temp文件夹中 三:详细设计 1. 主函数 完成变量的初始化与函数的定义之后,运用for( ; ; )来开启一个无限循环。循环内有switch函数来实现函数的选择功能,case1、case2等分 别执行不同的函数操作,每个函数中调用了相应的函数,并采用函数system("pause") ;暂停等待按键。在case6中采用函数exit(0)跳出循环。 下面在讲一下主函数中定义的n的作用,n的初值是1,当执行完case1中的函数input ( )后返回值为n+i,i为输入的成员数,返回值重新赋给n,n变为成员数,从而确定了之后 display()等函数循环中的终止条件。 2. 分函数 【1】添加 【2】显示 【3】删除 【4】查询 【5】修改 保存函数:【1】定义一个文件指针fp 【2】输入想创建的文件名称,如filename 【3】开辟文件,用fopen以"写"的方式打开,并把fp指针指向该文件 【4】在文件中输入信息 【5】保存(即fclose(filename)) 查询函数:运用了if来实现选择,并通过递归返回继续查询。 注:身份以及单位的查询方式有所不同,单位只能查找一条符合的记录,而按身份查询 可显示所有符合的信息。若查找不到,则返回继续查询,选择5返回则退出查询。 四:调试与测试 我们编写的函数具有一定的容错能力。具表现为 【1】如select函数中输入0-6以外的数,则循环继续进行,直到输入0-6为止 【2】sign!='n'&&sign!='N'语句保证了大小写不会影响结果 【3】while(m!='1'&&m!='2'&&m!='3'&&m!='4') { printf("输入错误,请重新选择:"); scanf("%c",&m); }保证了输入正确 【4】当输入的成员信息错误时,可通过修改函数进行改动 五:测试结果 1.主函数运行正常。通过for语句是界面循环,并有switch及system函数进行配合调节 达到目的。(界面显示如下) 2.测试结果:运行正常,达到了预订的目标。 此处为通过保存函数保存后的txt文本中的学生信息 六:心得 课程设计是一个不断学习、思考、编写、修改的过程。它对我们的能力提出了挑战。 我不仅意识到c语言基础的重要性,更意识到了自学能力的重要性,同学学习书本,查找 资料等多种途径来构建思
好的,下面是一个简单的用链表实现通讯录管理系统的示例代码: ```c #include <stdio.h> #include <stdlib.h> #include <string.h> // 定义通讯录结构 typedef struct contact { char name[20]; char phone[20]; struct contact *next; } Contact; // 声明函数 void add_contact(Contact **head); void delete_contact(Contact **head); void search_contact(Contact *head); void display_contacts(Contact *head); void save_contacts(Contact *head); int main() { Contact *head = NULL; // 初始化头指针为空 int choice; while (1) { printf("\n1. 添加联系人\n"); printf("2. 删除联系人\n"); printf("3. 查找联系人\n"); printf("4. 显示所有联系人\n"); printf("5. 保存联系人到文件\n"); printf("0. 退出\n"); printf("请输入选项:"); scanf("%d", &choice); switch (choice) { case 1: add_contact(&head); break; case 2: delete_contact(&head); break; case 3: search_contact(head); break; case 4: display_contacts(head); break; case 5: save_contacts(head); break; case 0: exit(0); default: printf("无效选项,请重新输入!\n"); } } return 0; } // 添加联系人 void add_contact(Contact **head) { Contact *new_contact = (Contact *) malloc(sizeof(Contact)); printf("请输入姓名:"); scanf("%s", new_contact->name); printf("请输入电话号码:"); scanf("%s", new_contact->phone); new_contact->next = *head; *head = new_contact; printf("联系人添加成功!\n"); } // 删除联系人 void delete_contact(Contact **head) { char name[20]; printf("请输入要删除的联系人姓名:"); scanf("%s", name); Contact *prev = NULL; Contact *current = *head; while (current != NULL && strcmp(current->name, name) != 0) { prev = current; current = current->next; } if (current == NULL) { printf("未找到联系人!\n"); return; } if (prev == NULL) { *head = current->next; } else { prev->next = current->next; } free(current); printf("联系人删除成功!\n"); } // 查找联系人 void search_contact(Contact *head) { char name[20]; printf("请输入要查找的联系人姓名:"); scanf("%s", name); Contact *current = head; while (current != NULL) { if (strcmp(current->name, name) == 0) { printf("姓名:%s,电话:%s\n", current->name, current->phone); return; } current = current->next; } printf("未找到联系人!\n"); } // 显示所有联系人 void display_contacts(Contact *head) { if (head == NULL) { printf("通讯录为空!\n"); return; } Contact *current = head; while (current != NULL) { printf("姓名:%s,电话:%s\n", current->name, current->phone); current = current->next; } } // 保存联系人到文件 void save_contacts(Contact *head) { if (head == NULL) { printf("通讯录为空!\n"); return; } FILE *fp = fopen("contacts.txt", "w"); if (fp == NULL) { printf("保存失败!\n"); return; } Contact *current = head; while (current != NULL) { fprintf(fp, "%s,%s\n", current->name, current->phone); current = current->next; } fclose(fp); printf("保存成功!\n"); } ``` 这个示例代码实现了添加、删除、查找、显示、保存联系人的功能,其中通讯录使用链表来存储,每个节点包括姓名、电话和下一个节点的指针。在添加联系人时,新的节点会插入到链表的头部;在删除联系人时,需要遍历链表找到要删除的节点并将其从链表中删除;在查找联系人时,也需要遍历链表并按姓名进行比较;在显示所有联系人时,只需要遍历链表并输出每个节点的信息;在保存联系人到文件时,可以使用文件 I/O 将每个节点的信息写入到一个文件中。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值