C语言期末项目——基于链表的通信录管理

news/2024/12/24 13:54:00 标签: c语言, 链表, 开发语言

一、项目介绍 

意义:对于一个通信录来说,要管理联系人的信息,包括编号,姓名,性别,电话。开发其系统主要为了帮助用户提高通讯录有管理效率,节约资源,提高信息的精确度

模块:
一级菜单内容


1> 注册模块:完成用户信息的注册用于登录管理系统
2> 登录模块:使用输入的登录账号和密码与文件存储信息对比
3> 退出系统

二级菜单内容:


3> 创建模块create:创建链表完成对通信录的存储
4> 添加数据add:添加通信录的信息放入链表
5> 查找信息find:可以通过姓名进行查找
6> 修改信息update:可以修改联系人信息并保存,修改联系人信息有包括了对联系人编号,姓名,性别,电话号码的分别修改,也可以同时对编号,姓名,性别,电话号码修改;
7> 删除信息delete:可根据输入的姓名进行删除
8> 插入信息insert:将给定的信息以及插入位置信息完成插入
9> 展示信息show:将通讯录的所有信息进行展示
11> 按照姓名将通讯录排序
12> 返回上一级

二、详细代码

源文件:(contact.c)

#include"contact.h"

adminPtr create()//创建头部
{
	adminPtr p=(adminPtr)malloc(sizeof(admin));
	if(NULL==p)
	{
		printf("创建失败\n");
		return NULL;
	}
	bzero(p->data,sizeof(p->data));
	p->len=0;
	return p;
}

int empt(adminPtr p)
{
	if(NULL==p)
	{
		printf("判空失败\n");
		return 0;
	}
	return p->len==0;
}

int full(adminPtr p)
{
	if(NULL==p)
	{
		printf("判满失败\n");
			return -1;
	}
	return p->len==MAX;
}

int insert(adminPtr p)
{
		if(NULL==p||full(p))
		{
			printf("插入失败\n");
			return -1;
		}
	//	admin_dataPtr p->data[p->len]=(admin_dataPtr)malloc(sizeof(admin_data));
		printf("请输入用户名\n");
		scanf("%s",p->data[p->len].name);//记录用户名
		printf("请输入用户密码\n");
		scanf("%s",p->data[p->len].pass);//记录密码
		p->len++;
		printf("注册成功\n");
		return 0;
}

int search(adminPtr p)
{
	if(NULL==p||empt(p))
		{
			printf("登录失败\n");
			return -1;
		}
		printf("请输入用户名\n");
		char n[30];
		scanf("%s",n);
		printf("请输入用户密码\n");
		char s[15];
		scanf("%s",s);

	for(int i=0;i<p->len;i++)
	{
		if(strcmp(p->data[i].name,n)==0 && strcmp(p->data[i].pass,s)==0)
			{
				return 3;
			}
			
			if(strcmp(p->data[i].pass,s)==0)
			{
				return 1;
			}
	
			if(strcmp(p->data[i].name,n)==0)
			{
				return 2;
		}

	}
	printf("查无此人\n");
	return 0;
}

ContactPtr Contact_create()
{
	ContactPtr p=(ContactPtr)malloc(sizeof(Contact));
	if(NULL==p)
	{
		printf("创建失败\n");
		return NULL;
	}
	p->lon=0;
	p->next=NULL;
	return p;
}

int Contact_empt(ContactPtr p)
{
	if(NULL==p)
	{
		printf("判空失败\n");
		return -1;
	}
	return p->lon==0;
}

int Contact_add(ContactPtr p)//二级通讯录信息插入
{
	ContactPtr h=Contact_create();//新节点
	if(NULL==h)
	{
		printf("创建失败\n");
		return -1;
	}
	h->Contact_Data=(Node_DataPtr)malloc(sizeof(Node_Data));//创建data类型
	if(NULL==h->Contact_Data)
	{
		printf("创建失败\n");
		return -1;
	}
	printf("请输入联系人编号\n");
	scanf("%d",&h->Contact_Data->id);
	printf("请输入联系人姓名\n");
	scanf("%s",h->Contact_Data->Admin_Name);//记录联系人姓名
	printf("请输入联系人性别\n");
	scanf("%s",h->Contact_Data->Six);
	printf("请输入联系人电话\n");
	scanf("%s",h->Contact_Data->Phone);

	ContactPtr p1=p;
	while(p1->next!=NULL)
	{
		p1=p1->next;
	}
	h->next=p1->next;//链表相连
	p1->next=h;
	printf("创建成功\n");
	p->lon++;
	p1=NULL;
	return 1;

}

void Contact_search(ContactPtr p)//通过姓名查找
{
	if(NULL==p||Contact_empt(p))
	{
		printf("查找失败\n");
	}
	printf("请输入要查找的姓名\n");
	char name[30];
	scanf("%s",name);
	ContactPtr p1=p;
	while(p1->next!=NULL)
	{
		p1=p1->next;
		if(strcmp(p1->Contact_Data->Admin_Name,name)==0)
		{
			break;
		}
	}
		printf("ID:%d\t",p1->Contact_Data->id);
		printf("姓名:%s\t",p1->Contact_Data->Admin_Name);
		printf("性别:%s\t",p1->Contact_Data->Six);
		printf("电话:%s\n",p1->Contact_Data->Phone);
		p1=NULL;
	return ;

}
void Contact_change(ContactPtr p)//修改信息
{
	if(NULL==p||Contact_empt(p))
	{
		printf("修改失败\n");
		return ;
	}
	char name[30];
	printf("请输入要修改的联系人姓名\n");
	scanf("%s",name);
	ContactPtr p1=p;
	int flag=1;
	while(p1->next!=NULL)
	{
		p1=p1->next;
		if(strcmp(p1->Contact_Data->Admin_Name,name)==0)
		{
			flag=0;
			break;
		}
	}
	if(flag==0)
	{
		printf("请输入修改后的联系人编号\n");
		scanf("%d",&p1->Contact_Data->id);
		printf("请输入修改后联系人姓名\n");
		scanf("%s",p1->Contact_Data->Admin_Name);
		printf("请输入修改后联系人性别\n");
		scanf("%s",p1->Contact_Data->Six);
		printf("请输入修改后的联系人电话\n");
		scanf("%s",p1->Contact_Data->Phone);	
		p1=NULL;
		return ;
	}
	else if(flag==1)
	{
		printf("查无此人\n");
		return ;
	}
}
void Contact_del(ContactPtr p)//删除信息
{
	if(NULL==p||Contact_empt(p))
	{
		printf("删除失败\n");
		return ;
	}
	char name[30];
	printf("请输入要删除的联系人姓名\n");
	scanf("%s",name);
	ContactPtr p1=p;
	int	flag=1;
	while(p1!=NULL)
	{
		if(strcmp(p1->next->Contact_Data->Admin_Name,name)==0)
		{
			flag=0;
			break;
		}
		p1=p1->next;
	}
	if(flag==0)
	{
		ContactPtr temp=p1->next;
		p1->next=p1->next->next;
		free(temp);
		temp=NULL;
		p1=NULL;
		p->lon--;
		return ;
	}
	else if(flag==1)
	{
		printf("查无此人\n");
		return ;
	}
}
void Contact_insert(ContactPtr p)//插入信息
{
	if(NULL==p)
	{
		printf("插入失败\n");
		return ;
	}
	ContactPtr h=Contact_create();//新节点
	if(NULL==h)
	{
		printf("创建失败\n");
		return; 
	}

	h->Contact_Data=(Node_DataPtr)malloc(sizeof(Node_Data));//创建data类型
	if(NULL==h->Contact_Data)
	{
		printf("创建失败\n");
		return ;
	}
	int a=0;//插入位置
	printf("请输入插入位置\n");
	scanf("%d",&a);//输入插入位置
	printf("请输入联系人编号\n");
	scanf("%d",&h->Contact_Data->id);
	printf("请输入联系人姓名\n");
	scanf("%s",h->Contact_Data->Admin_Name);//记录联系人姓名
	printf("请输入联系人性别\n");
	scanf("%s",h->Contact_Data->Six);
	printf("请输入联系人电话\n");
	scanf("%s",h->Contact_Data->Phone);

	ContactPtr p1=p;
	for(int i=0;i<a-1;i++)//遍历到要插入位置
	{
		p1=p1->next;
	}
	h->next=p1->next;//先链接后续节点
	p1->next=h;//在链接前驱节点
	p->lon++;
	return ;

}
void Contact_show(ContactPtr p)//遍历信息
{
	if(NULL==p||Contact_empt(p))
	{
		printf("展示失败\n");
		return ;
	}
	ContactPtr p1=p;
	while(p1->next!=NULL)
	{
		p1=p1->next;
		printf("ID:%d\t",p1->Contact_Data->id);
		printf("姓名:%s\t",p1->Contact_Data->Admin_Name);
		printf("性别:%s\t",p1->Contact_Data->Six);
		printf("电话:%s\n",p1->Contact_Data->Phone);
	}
	return ;
}
void Contact_sort(ContactPtr p)//按姓名将通讯录排序
{
	if(NULL==p||Contact_empt(p))
	{
		printf("排序失败\n");
		return ;
	}
	ContactPtr p1=p;
	ContactPtr temp=p;
	int flag=1;
	for(int i=0;i<p->lon-1;i++)//使用冒泡排序
	{
		while(p1->next && p1->next->next)//内层循环
		{
			if(strncmp(p1->next->Contact_Data->Admin_Name,p1->next->next->Contact_Data->Admin_Name,1)>0)//进行第一个字符大小比较
			{//实现链表节点的交换
				temp=p1->next;
				p1->next=p1->next->next;
				temp->next=p1->next->next;
				p1->next->next=temp;
			}
			p1=p1->next;
		}
		p1=p;
	}
	return ;
}

头文件:(contact.h) 

#ifndef __ConTact__
#define __ConTact__
#include<stdio.h>
#include<stdlib.h>
#include<string.h>

#define MAX 30

typedef struct admindata//用户名与密码
{
	char name[30];
	char  pass[15];
}admin_data;//重命名类型

typedef struct admin//用户名节点
{
		admin_data data[MAX];
		int len;
}admin,*adminPtr;

typedef struct Node //通讯录信息
{
	int id;
	char Admin_Name[30];
	char Six[10];
	char Phone[15];
}Node_Data,*Node_DataPtr;

typedef struct contact//通讯录节点
{
	union
	{
		Node_DataPtr Contact_Data;
		int lon;
	};
	struct contact *next;
}Contact,*ContactPtr;

adminPtr create();//创建链表,记录用户名与密码

int  insert(adminPtr p);//数据入链表,注册信息

int  search(adminPtr p);//遍历,查找用户名与密码

int  menu();

ContactPtr Contact_create();//创建链表,记录通讯录

int Contact_empt(ContactPtr p);

int Contact_add(ContactPtr p);//通讯录信息录入

void Contact_search(ContactPtr p);//通过姓名查找

void Contact_change(ContactPtr p);//修改信息

void Contact_del(ContactPtr p);//根据姓名删除信息

void Contact_insert(ContactPtr p);//插入信息

void Contact_show(ContactPtr p);//遍历信息

void Contact_sort(ContactPtr p);//按姓名将通讯录排序

#endif

主程序:(main.c) 

#include"contact.h"
int main(int argc, const char *argv[])
{
	int n=0;
	int flag=1;
	adminPtr p=create();//创建头结点
	while(flag==1)
	{
		printf("/************************************/\n");
		printf("1,登录\t2.注册\t3.退出\n");
		printf("/***********************************/\n");

		printf("\t请选择功能\n");
		scanf("%d",&n);
		switch(n)
		{
			case 1:
				{
					int a=0;
					a=search(p);//遍历链表,查找信息
					if(1==a)
					{
						printf("用户名错误\n");
					}
					else if(2==a)
					{
						printf("密码错误\n");
					}
					else if(3==a)
					{
						menu();
					}
					break;
				}
			case 2:
				{
					insert(p);//调用入链函数
					break;
				}
			case 3:
				{
					flag=0;
				}
		}
	}
	return 0;
}


int  menu()
{
	int n2=0;
	int flag2=1;
	static ContactPtr p2=NULL;
	p2=Contact_create();//创建头结点
	while(flag2==1)
	{
	printf("/************************************/\n");
	printf("1,增加信息\t2.查找信息\t3.修改信息\n");
	printf("4.删除信息\t5.插入信息\t6.展示信息\n");
	printf("7.按姓名排序\t8.返回上一级\n");
	printf("/***********************************/\n");

		printf("\t请选择功能\n");
		scanf("%d",&n2);
		switch(n2)
		{
			case 1:
				{
					Contact_add(p2);//通讯录信息录入
					break;
				}
			case 2:
				{
					Contact_search(p2);
					break;
				}
			case 3:
				{
					Contact_change(p2);//修改信息
					break;
				}
			case 4:
				{
					Contact_del(p2);//根据姓名删除信息
					break;
				}
			case 5:
				{
					Contact_insert(p2);//插入信息
					break;
				}
			case 6:
				{
					Contact_show(p2);//展示信息
					break;
				}
			case 7:
				{
					Contact_sort(p2);//按姓名将通讯录排序
					break;
				}
			case 8:
				{
					flag2=0;
				}
		}
	}
	return 0;

}

运行截图:

 本程序使用strcmp函数对姓名首字母进行比较,因此具体汉字无法实现比较。

功能较多,使用无问题,再次仅演示排序功能。


http://www.niftyadmin.cn/n/5797859.html

相关文章

queue中的offer方法与add方法的区别

在Java中&#xff0c;Queue接口提供了两种向队列中添加元素的方法&#xff1a;add()和offer()。这两种方法在功能上相似&#xff0c;但在处理队列满的情况时行为有所不同3。以下是它们的主要区别&#xff1a; 1.异常处理 add()&#xff1a;如果队列已满&#xff0c;add()方法会…

蓝牙BLE开发——解决iOS设备获取MAC方式

解决iOS设备获取MAC方式 uniapp 解决 iOS 获取 MAC地址&#xff0c;在Android、iOS不同端中互通&#xff0c;根据MAC 地址处理相关的业务场景&#xff1b; 文章目录 解决iOS设备获取MAC方式监听寻找到新设备的事件BLE工具效果图APP监听设备返回数据解决方式ArrayBuffer转16进制…

GESP CCF C++六级编程等级考试认证真题 2024年12月

GESP CCF C六级编程等级考试认证真题 202412 1 单选题&#xff08;每题 2 分&#xff0c;共 30 分&#xff09; 第 1 题 面向对象编程(OOP)是一种特殊的程序设计方法。下面( )不是重要的OOP特性。 A. 抽象 B. 封装 C. 继承 D. 模块化 第 2 题 以下关于C中类的说法&#xff0c;…

1.使用 Couchbase 数仓和 Temporal(一个分布式任务调度和编排框架)实现每 5 分钟的增量任务

在使用 Couchbase 数仓和 Temporal&#xff08;一个分布式任务调度和编排框架&#xff09;实现每 5 分钟的增量任务时&#xff0c;可以按照以下步骤实现&#xff0c;同时需要注意关键点。 实现方案 1. 数据层设计&#xff08;Couchbase 增量存储与标记&#xff09; 在 Couchb…

UML图【重要】

文章目录 2.1 类图概述2.2 类图的作用2.3 类图表示法2.3.1 类的表示方式2.3.2 类与类之间关系的表示方式2.3.2.1 关联关系2.3.2.2 聚合关系2.3.2.3 组合关系2.3.2.4 依赖关系2.3.2.5 继承关系2.3.2.6 实现关系 统一建模语言&#xff08;Unified Modeling Language&#xff0c;U…

使用Vue+Django开发的旅游路书应用

基于Django设计的低代码后端框架调用高德地图接口实现定位搜索、路线规划等功能 体验地址

深入理解Redis

1.数据结构类型 数据结构-SDS-简单动态字符串 Redis构建了一种新字符串结构,称为简单动态字符串(Simple Dynamic String),简称SDS。 Redis未直接使用C语言的字符串,如:char* s = "hello",本质是字符数组: {h, e, l, l, o, \0}。因为C语言字符串存在很多问题…

gitlab克隆仓库报错fatal: unable to access ‘仓库地址xxxxxxxx‘

首次克隆仓库&#xff0c;失效了&#xff0c;上网查方法&#xff0c;都说是网络代理的问题&#xff0c;各种清理网络代理后都无效&#xff0c;去问同事&#xff1a; 先前都是直接复制的网页url当做远端url&#xff0c;或者点击按钮‘使用http克隆’ 这次对于我来说有效的远端u…