如有bug望指正 谢谢

头文件
#ifndef __HEAD_H__
#define __HEAD_H__

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

//信息结构体
typedef struct info
{
	int  id;
	char name[128];
	char gender[10];
	char tele[20];
	struct info* next;
}info,*info_m;

//链结构体
typedef struct link
{
	int len;
	info_m front;
	info_m rear;
}link,*link_k;

//登录结构体
typedef struct log
{
	char username[128];
	char password[128];
	int length;
	struct log* pass;
}log,*log_g;

//一级菜单函数声明↓
//1、注册模块 将注册的信息存入结构体中
void register_login(log_g G,link_k L);
//2、登录模块
void log_in(log_g G,link_k L);
//3、退出系统
void exit();

//1. 申请账户存储空间
log_g create_log();
//2. 添加新用户
void add_log(log_g G);
//3. 退出系统
void exit_system();


//一级菜单页面
void menu_login(log_g G,link_k L);
//二级菜单页面
void menu_info(link_k L,log_g G);
//辅助功能菜单栏
void menu_assist(link_k L,log_g G);



//二级菜单函数声明↓
//1、create 创建链表 完成对信息的存储
link_k create_link();
//2、add 添加数据 添加通讯录的信息放入链中
void add_info(link_k L);
//3、find 查找信息 可以通过姓名进行查找
void find_info(link_k L);
//4、updata_select 修改信息 可以修改联系人信息并保存 分别修改 同时修改
void updata_select(link_k L);
//4.1 updata_all
void updata_info(link_k L);
//4.2 updata_part
void updata_part(link_k L);
//5、delete 删除信息 可以根据输入的姓名进行删除
void delete_info(link_k L);
//6、insert 插入信息 将给定的信息以及插入位置信息完成插入
void insert_info(link_k L);
//7、show 展示信息 将通讯录的所有信息进行展示
void show_info(link_k L);
//8、按照姓名将通讯录排序
void sort_info(link_k L);

//辅助功能函数声明↓
//10、初始化链表init:将链表进行初始化
void bzero_info(link_k L);
//11、获取链表长度getlength
void getlength_info(link_k L);
//12、统计性别;
void stat_gender(link_k L);
//13、释放链表空间
void destroy_link(link_k* L);
#endif
功能函数
#include "head.h"

//二级菜单
//1、create 创建链表 完成对信息的存储
link_k create_link()
{
	link_k L = (link_k)malloc(sizeof(link));
	if (L == NULL)
		return NULL;
	L->front = NULL;
	L->rear = NULL;
	L->len  = 0;
	return L;
}
//2、add 添加数据 添加通讯录的信息放入链中
void add_info(link_k L)
{
	info_m new = (info_m)malloc(sizeof(info));
	if (new == NULL)
		return;
	printf("编号:");scanf("%d",&new->id);
	info_m p = L->front;
	while(p != NULL)
	{
		if (new->id == p->id)
		{
			printf("\n该编号已存在!即将放回上页面......\n");
			return;
		}
		p = p->next;
	}
	printf("姓名:");scanf("%s",new->name);
	printf("性别(man/woman):");scanf("%s",new->gender);
	printf("电话:");scanf("%s",new->tele);
	if (L->rear == NULL)
	{
		L->front = new;
		L->rear  = new;
	}
	else
	{
		L->rear->next = new;
		L->rear = new;
	}
	L->len++;
	printf("该成员数据添加成功!\n");
}
//3、find 查找信息 可以通过姓名进行查找
void find_info(link_k L)
{
	if (L == NULL)
		return;
	if (L->len == 0)
	{
		printf("没有人员信息录入,返回上一级\n");
		return;
	}
	char name[128];
	int found = 0;
	printf("name=");
	scanf("%s",name);
	info_m p = L->front;
	while(p != NULL)
	{
		if(strcmp(name,p->name)==0)
		{
			found =1;
			break;
		}
		p = p->next;
	}
	if (found == 1)
	{
		printf("\n该人员信息如下:\n");
		printf("%d\t",p->id);
		printf("%s\t",p->name);
		printf("%s\t",p->gender);
		printf("%s\t\n",p->tele);
	}
	if (found == 0)
	{
		printf("\n没有记录该人员,请检查输入是否有误!\n");
	}
}
//4.1 updata_all 
void updata_info(link_k L)
{
	if (L == NULL)
		return;
	printf("\n请选择您要修改的对象名字:");
	char name[128];
	int found = 0;
	scanf("%s",name);
	info_m p = L->front;
	while(p != NULL)
	{
		if(strcmp(name,p->name)==0)
		{
			found = 1;
			break;
		}
		p = p->next;
	}
	if (found == 1)
	{
		printf("该人员信息如下:\n");
		printf("请输入新的编号(原编号为%d):",p->id);
		scanf("%d",&p->id);	
		printf("请输入新的名字(原名字为%s):",p->name);
		scanf("%s",p->name);
		printf("请输入新的性别(原性别为%s):",p->gender);
		scanf("%s",p->gender);
		printf("请输入新的电话(原电话为%s):",p->tele);
		scanf("%s",p->tele);
//		printf("变更后的结果如下:");
//		printf("%d\t",p->id);
//		printf("%s\t",p->name);
//		printf("%s\t",p->gender);
//		printf("%s\t\n",p->tele);
	}
	if (found == 0)
	{
		printf("没有记录该人员,请检查输入是否有误!\n");
	}
}
//4.2 updata_part
void updata_part(link_k L)
{
	int choice = 0;
	printf("\n===== 请输入你的选择:=====\n");
	printf("1.修改编号\n");
	printf("2.修改姓名\n");
	printf("3.修改性别\n");
	printf("4.修改电话\n");
	printf("\n请输入您的选择:");
	scanf("%d",&choice);
	switch(choice)
	{
	case 1:{
			   printf("\n请选择您要修改的对象名字:");char name[128];
			   int found = 0 ;scanf("%s",name);info_m p = L->front;
			   while(p != NULL){
				   if(strcmp(name,p->name)==0){
					   found = 1;break;}
				   p = p->next;}
			   if(found == 1){
				   printf("请输入新的编号(原编号为%d):",p->id);
				   scanf("%d",&p->id);return;}
			   if(found == 0){
				   printf("没有记录该人员,请检查输入是否有误!\n");}
			   break;}

	case 2:{
			   printf("\n请选择您要修改的对象名字:");char name[128];
			   int found = 0;scanf("%s",name);info_m p = L->front;
			   while(p != NULL){
				   if(strcmp(name,p->name)==0){
					   found = 1;break;}
				   p = p->next;}
			   if(found == 1){
				   printf("请输入新的名字(原名字为%s):",p->name);
				   scanf("%s",p->name);return;}
			   if(found == 0){
				   printf("没有记录该人员,请检查输入是否有误!\n");}
			   break;}

	case 3:{
			   printf("\n请选择您要修改的对象名字:");char name[128];
			   int found = 0;scanf("%s",name);info_m p = L->front;
			   while(p != NULL){
				   if(strcmp(name,p->name)==0){
					   found = 1;break;}
				   p = p->next;}
			   if(found == 1){
				   printf("请输入新的性别(原性别为%s):",p->gender);
				   scanf("%s",p->gender);return;}
			   if(found == 0){
				   printf("没有记录该人员,请检查输入是否有误!\n");}
			   break;}

	case 4:{
			   printf("\n请选择您要修改的对象名字:");char name[128];
			   int found = 0;scanf("%s",name);info_m p = L->front;
			   while(p != NULL){
				   if(strcmp(name,p->name)==0){
					   found = 1;break;}
				   p = p->next;}
			   if(found == 1){
				   printf("请输入新的电话(原电话为%s):",p->tele);
				   scanf("%s",p->tele);return;}
			   if(found == 0){
				   printf("没有记录该人员,请检查输入是否有误!\n");}
			   break;}
			 
	default:printf("\n选择无效!\n");break;
	}
}
//4、updata_select 修改信息 可以修改联系人信息并保存 分别修改 同时修改 
void updata_select(link_k L)
{
	int choice = 0;
	printf("\n===== 请输入你的选择:=====\n");
	printf("1.进行全部修改\n");
	printf("2.对部分进行修改\n");
	printf("3.退出\n");
	printf("\n请输入您的选择:");
	scanf("%d",&choice);
	switch(choice)
	{
	case 1:updata_info(L);break;
	case 2:updata_part(L);break;
	case 3:printf("\n即将退出选择...\n");break;
	default:printf("\n选择无效!\n");break;
	}
}
//5、delete 删除信息 可以根据输入的姓名进行删除
void delete_info(link_k L)
{
	if (L == NULL || L->len == 0)
		return;
	printf("\n请选择您要删除的对象名字:");
	char name[128];
	scanf("%s",name);

	info_m p = L->front; 		//p从头开始
	info_m q = p; 				//q保留p的位置 用于记录
	int found = 0;
	char flag[10];
	
	while(p != NULL)
	{
		if (strcmp(name,p->name) == 0)
		{
			found = 1;
			break;
		}
		q = p; 					//p在交换成下一个前 保存p的位置
		p = p->next; 			//p循序往下走
	}
	if (found == 0)
	{
		printf("\n没有记录该人员,请检查输入是否有误!\n");
		return;
	}
	if (found == 1)
	{
		printf("\n是否确认要删除!!!\n");
		printf("(yes/no):");
		scanf("%s",flag);

		if (strcmp(flag,"yes") == 0)
		{
			if (p == L->front)  	//头删
			{
				L->front = p->next;
				if (L->rear == p)
				{
					L->rear = NULL;
				}
			}

			q->next = p->next; 		//中间删

			if (p == L->rear) 		//尾删
			{
				L->rear = q;
			}
			free(p);
			L->len--;
			printf("删除成功!\n");
		}
		else
			return;
	}
}
//6、insert 插入信息 将给定的信息以及插入位置信息完成插入
void insert_info(link_k L)
{
	info_m new_pos = (info_m)malloc(sizeof(info));
	if (new_pos == NULL)
		return;

	info_m p = L->front;
	printf("\n给定以下信息\n");
	printf("编号:");scanf("%d",&new_pos->id);
	while(p != NULL)
	{
		if (new_pos->id == p->id)
		{
			printf("\n该编号已存在!即将返回上一页面......\n");
			return;
		}
		p = p->next;
	}
	printf("姓名:");scanf("%s",new_pos->name);
	printf("性别(man/woman):");scanf("%s",new_pos->gender);
	printf("电话:");scanf("%s",new_pos->tele);

	int pos;
	printf("\n请输入要插入的位置:");
	scanf("%d",&pos);
	
	if (pos == 0)
	{
		new_pos->next = L->front;
		L->front  = new_pos;
		if (L->rear == NULL)
			L->rear = new_pos;
		L->len++;
		return;
	}
	if (pos > 0 && pos <= L->len)
	{
		info_m start = L->front;
		for(int i=1;i<pos;i++)
		{
			start = start->next; 
		} //遍历找到pos前的位置
		new_pos->next = start->next;
		start->next = new_pos;
		if (new_pos->next == NULL)
		{	
			L->rear = new_pos;
		}
		L->len++;
		return;
	}
	else
	{
		printf("\n插入不合理\n");return;
	}
}
//7、show 展示信息 将通讯录的所有信息进行展示
void show_info(link_k L)
{
	info_m p = L->front;
	if (L->len == 0)
	{
		printf("\n没有人员信息录入!\n");
		return;
	}
	printf("\n编号\t姓名\t性别\t电话\t\n");
	while(p != NULL)
	{
//		printf("编号\t姓名\t性别\t电话\t\n");
		printf("%d\t",p->id);
		printf("%s\t",p->name);
		printf("%s\t",p->gender);
		printf("%s\t\n",p->tele);
//		printf("一共有%d人。\n",L->len);
		p=p->next;
	}
	printf("所有信息输出完成,一共有%d人。\n",L->len);
}
//8、按照姓名将通讯录排序
void sort_info(link_k L)
{
	if (L == NULL || L->len <= 1)
		return;
	int swapped;
	info_m p;
	info_m last = NULL;
	do{
		swapped = 0;
		p = L->front;
		while(p->next != last)
		{
			if(strcmp(p->name,p->next->name)>0)
			{
				info_m temp = p->next;
				p->next = temp->next;
				temp->next = p;
				if(p == L->front)
				{
					L->front = temp;
				}
				else
				{
					info_m pre = L->front;
					while(pre->next != p)
					{
						pre = pre->next;
					}
					pre->next = temp;
				}
				swapped = 1;
			}
			else
			{
				p = p->next;
			}
		}
		last = p;
	}while(swapped);
}
//9、放回上一级

//辅助功能
//10、初始化链表init:将链表进行初始化
void bzero_info(link_k L)
{
	if (L == NULL)
		return;
	bzero(L,sizeof(link));
	L->front = NULL;
	L->rear  = NULL;
	L->len   = 0;
}
//11、获取链表长度getlength
void getlength_info(link_k L)
{
	if (L == NULL)
		return;
	int getlength;
	getlength = (L->len)*sizeof(link);
	printf("getlength=%d\n",getlength);
	printf("链表长度为%d\n",L->len);
}
//12、统计性别;
void stat_gender(link_k L)
{
	if (L == NULL)
		return;
	info_m p = L->front;
	int count = 0;
	char gender[128]="woman";
	while(p != NULL)
	{
		if(strcmp(gender,p->gender) == 0)
		{
			count++;
		}
		p = p->next;
	}
	int boy = L->len - count;
	printf("\n性别为女性的有%d人\n",count);
	printf("性别为男性的有%d人\n",boy);
	printf("总计有%d人\n",L->len);
}
//13、释放链表空间
void destroy_link(link_k* L)
{
	if (*L == NULL|| L == NULL)
		return;
	free(*L);
	*L = NULL;
}


菜单栏函数
#include "head.h"

//一级菜单
//1、注册模块 将注册的信息存入结构体中
void register_login(log_g G,link_k L)
{
	if (G == NULL)
		return;
	add_log(G);
	printf("回到上一界面!\n");
//	menu_login(G,L);
}
//2、登录模块
void log_in(log_g G,link_k L)
{
	char username[128];
	char password[128];
	printf("\n请输入你的账号:");
	scanf("%s",username);
	printf("请输入您的密码: ");
	scanf("%s",password);
	if(strcmp(username,G->username)==0 && strcmp(password,G->password)==0)
	{
		printf("登录成功!\n");
		menu_info(L,G);
	}
	else
	{
		printf("登录失败,账号或密码错误...\n");
//		menu_login(G,L);
	}
	return;
}

//一级菜单页面
void menu_login(log_g G,link_k L)
{
	int choice = 0;
	do
	{
		printf("\n======== 登录页面 ========\n");
		printf("1.注册账号\n");
		printf("2.登录\n");
		printf("3.退出系统\n");
//		int choice = 0;
		printf("\n请输入您的选择:");
		scanf(" %d",&choice);
		switch(choice)
		{
		case 1:register_login(G,L);break;
		case 2:log_in(G,L);break;
		case 3:exit_system;break;
		default:printf("\n选择无效!\n");
		}
	}while(choice!=3);
}

//二级菜单页面
void menu_info(link_k L,log_g G)
{
	int choice=0;
	do{
		printf("\n======== 功能页面 ========\n");
		printf("1.录入新用户信息\n");
		printf("2.查找用户信息\n");
		printf("3.修改用户信息\n");
		printf("4.删除用户信息\n");
		printf("5.插入用户信息\n");
		printf("6.展示所有用户信息\n");
		printf("7.按照姓名进行排序\n");
		printf("8.返回上一级\n");
		printf("9.辅助功能\n");
		printf("\n请输入您的选择:");
		scanf("%d",&choice);
		switch(choice)
		{
		case 1:add_info(L);break;
		case 2:find_info(L);break;
		case 3:updata_select(L);break;
		case 4:delete_info(L);break;
		case 5:insert_info(L);break;
		case 6:show_info(L);break;
		case 7:sort_info(L);break;
		case 8:return;
		case 9:menu_assist(L,G);break;
		case 10:printf("开发中...\n");break;
		default:printf("\n无效的选择!\n");
		}
	}while(choice!=10);
}

//辅助功能菜单栏
void menu_assist(link_k L,log_g G)
{
	int choice = 0;
	do{
		printf("\n======== 辅助功能页面 ========\n");
		printf("1.初始化链表\n");
		printf("2.获取链表长度\n");
		printf("3.统计性别\n");
		printf("4.返回上一级\n");
		printf("\n请输入您的选择:");
		scanf("%d",&choice);
		switch(choice)
		{
		case 1:bzero_info(L);break;
		case 2:getlength_info(L);break;
		case 3:stat_gender(L);break;
		case 4:;return;
		default:printf("\n无效的选择!\n");
		}
	}while(choice!=4);
}


 




//1. 申请账户存储空间
log_g create_log()
{
	log_g G = (log_g)malloc(sizeof(log));
	if (G == NULL)
		return NULL;
	return G;
}
//2. 添加新用户
void add_log(log_g G)
{
	if (G == NULL)
		return;
	printf("\n请输入您的用户名:");scanf("%s",G->username);
	printf("请输入您的密码:");scanf("%s",G->password);
	G->length++;
	printf("\n注册成功!\n");
}
//3. 退出系统
void exit_system()
{
	printf("\n即将退出系统.......\n");
	exit(0);
}
makefile

EXE=login
Filename=$(wildcard *.c)
Objs=$(patsubst %.c,%.o,$(Filename))
CC=gcc
CFlags= -c -o
login=$(wildcard *.h)

all=$(EXE)
$(EXE):$(Objs)
	$(CC) $^ -o $@
%.o:%.c
	$(CC) $< $(CFlags) $@
.PHONY:clean
clean:
	rm $(EXE) $(Objs)

基于链表的通讯录管理

基于链表的通讯录管理
本代码有以下三个结构体
1、信息结构体
typedef struct info
{
    int  id;
    char name[128];
    char gender[10];
    char tele[20];
    struct info* next;
}info,*info_m;

2、链结构体
typedef struct link
{
    int len;
    info_m front;
    info_m rear;
}link,*link_k;

3、登录结构体
typedef struct log
{
    char username[128];
    char password[128];
    int length;
    struct log* pass;
}log,*log_g;

有以下功能👇
通过结构体3实现用户的注册和登录完成一级菜单设置

在二级菜单内
在堆区申请空间 使用malloc函数
添加数据 添加通讯录的信息放入链中 
先遍历一次链表 判断输入的编号是否存在 
已有则无法输入 若无则可以继续添加 长度+1

查找信息 修改信息 删除信息 插入信息 都根据姓名来进行匹配

输出信息的时候直接从头开始遍历链表 输出信息

给定信息插入时 会匹配pos的值 看插入是否合理 不合理结束

根据姓名进行排序时 使用冒泡排序 同时设定一个标志
在遍历链表过程中 前后两两比较 发生交换时标志为1
当无法交换时标志为0 结束循环 冒泡升序排序完成


辅助功能页面
初始化链表内 使用bzero清零
统计性别模块 让链表中的gender与设定的“man/woman”strcmp
有一次匹配则计数器+1 直至遍历完链表

最后执行完成后 退出系统时 free(*L)链表
 

更多推荐