contact.h
#ifndef __CONTACT_H__
#define __CONTACT_H__
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
//定义人员类型结构体
typedef struct Person
{
int id;
char name[20];
char sex;
char tel[20];
} datatype;
//定义节点结构体类型
typedef struct Node
{
union
{
datatype data;
int len;
};
struct Node *prior;
struct Node *next;
} *DoubleLoop,Node;
//创建
DoubleLoop list_create();
//链表初始化
void list_init(DoubleLoop L);
//申请节点封装数据
DoubleLoop apply_node(datatype e);
//尾插
int list_insert_tail(DoubleLoop L,datatype e);
//展示所有信息
void list_show(DoubleLoop L);
//按名字查找信息
int list_find_name(DoubleLoop L,char* name);
//按参数查找信息
int list_find_data(DoubleLoop L,datatype data);
//修改联系人信息
int list_update_contacts(DoubleLoop L,datatype e);
//按姓名进行删除
int list_delete_name(DoubleLoop L,char* name);
//按位置及给定信息插入
int list_insert_pos(DoubleLoop L,int pos,datatype e);
//将链表信息导入到文件中
int export_info_to_file(DoubleLoop L);
//按照姓名将通讯录排序
void list_sort_name(DoubleLoop L);
//获取链表长度
int getLength(DoubleLoop L);
//统计性别
void calculate_sex(DoubleLoop L);
//元素交换函数
void swap(datatype *a,datatype *b);
#endif
contact.c
#include "contact.h"
//创建
DoubleLoop list_create()
{
DoubleLoop L = (DoubleLoop)malloc(sizeof(Node));
if (NULL == L)
{
printf("双向循环链表创建失败\n");
return NULL;
}
list_init(L);
printf("双向循环链表创建成功\n");
return L;
}
//链表初始化
void list_init(DoubleLoop L)
{
//链表长度初始化
L->len = 0;
L->next = L;
L->prior = L;
printf("链表初始化成功\n");
}
//申请节点封装数据
DoubleLoop apply_node(datatype e)
{
//申请节点封装数据
DoubleLoop p = (DoubleLoop)malloc(sizeof(Node));
if (NULL == p)
{
printf("节点申请失败\n");
return NULL;
}
p->data = e;
p->next = NULL;
p->prior = NULL;
}
//添加数据==> 尾插
int list_insert_tail(DoubleLoop L,datatype e)
{
if (NULL == L)
{
printf("所给链表不合法\n");
return -1;
}
//申请节点
DoubleLoop p = apply_node(e);
/*
//采用头插法进行插入
p->next = L->next;
L->next->prior = p;
L->next = p;
p->prior = L;
*/
//采用尾插法
DoubleLoop q = L->next;
while (q->next!=L)
{
q=q->next;
}
p->next = q->next;
p->prior= q;
q->next = p;
L->prior = p;
//表长变化
L->len++;
printf("%s 双向循环链表尾插成功\n",e.name);
}
//展示所有人员信息
void list_show(DoubleLoop L)
{
if (NULL == L || L->next == L)
{
printf("遍历失败\n");
return;
}
//定义遍历指针,从第一个节点出发
DoubleLoop q = L->next;
printf("所有人员信息如下:\n");
printf("编号\t姓名\t性别\t电话\t\t\n");
while (q!= L)
{
printf("%d\t%s\t%c\t%s\t\t\n",q->data.id,q->data.name,q->data.sex,q->data.tel);
q = q->next;
}
printf("\n");
}
//根据姓名查找信息
int list_find_name(DoubleLoop L,char* name)
{
if (NULL == L)
{
printf("所给链表不合法\n");
return -1;
}
if (strlen(name) == 0)
{
printf("所给名字不能为空\n");
return -2;
}
//定义遍历指针,从第一个节点出发
DoubleLoop q = L->next;
int flag = 0;
while (q!= L)
{
//进行对比
if (strcmp(q->data.name,name) == 0)
{
printf("%s的信息已找到,详细信息如下\n",name);
printf("编号\t姓名\t性别\t电话\t\t\n");
printf("%d\t%s\t%c\t%s\t\t\n",q->data.id,q->data.name,q->data.sex,q->data.tel);
flag = 1;
return flag;
}
q = q->next;
}
if (flag == 0)
{
printf("%s的信息未找到\n",name);
return flag;
}
}
//按参数查找信息
int list_find_data(DoubleLoop L,datatype data)
{
if (NULL == L)
{
printf("所给链表不合法\n");
return -1;
}
//定义遍历指针,从第一个节点出发
DoubleLoop q = L->next;
int flag = 0;
while (q!= L)
{
//进行对比
if (strcmp(q->data.name,data.name) == 0)
{
printf("姓名为%s的信息已找到\n",data.name);
flag = 1;
return flag;
}
if (q->data.id == data.id)
{
printf("id%d的信息已找到\n",data.id);
flag = 1;
return flag;
}
if (strcmp(q->data.tel,data.tel) == 0)
{
printf("电话为%s的信息已找到\n",data.tel);
flag = 1;
return flag;
}
q = q->next;
}
if (flag == 0)
{
if (strcmp(q->data.name,data.name) == 0)
{
printf("%s的信息未找到\n",data.name);
}
if (q->data.id == data.id)
{
printf("id%d的信息未找到\n",data.id);
}
if (strcmp(q->data.tel,data.tel) == 0)
{
printf("电话为%s的信息未找到\n",data.tel);
}
return flag;
}
}
//修改联系人信息
int list_update_contacts(DoubleLoop L,datatype e)
{
if (NULL == L)
{
printf("所给链表不合法\n");
return -1;
}
int result = list_find_data(L,e);
if (result <=0)
{
printf("要修改的信息查找失败,无法进行修改\n");
return result;
}
DoubleLoop q = L->next;
while (q!= L)
{
//进行对比
if (strcmp(q->data.name,e.name) == 0)
{
printf("对姓名为%s的信息进行修改\n",e.name);
strcpy(q->data.name,e.name);
q->data.id = e.id;
q->data.sex = e.sex;
strcpy(q->data.tel,e.tel);
printf("对姓名为%s的信息进行修改成功\n",e.name);
return 1;
}
if (q->data.id == e.id)
{
printf("对id为%d的信息进行修改\n",e.id);
strcpy(q->data.name,e.name);
q->data.id = e.id;
q->data.sex = e.sex;
strcpy(q->data.tel,e.tel);
printf("对id为%d的信息进行修改成功\n",e.id);
return 1;
}
if (strcmp(q->data.tel,e.tel) == 0)
{
printf("对电话为%s的信息进行修改\n",e.tel);
strcpy(q->data.name,e.name);
q->data.id = e.id;
q->data.sex = e.sex;
strcpy(q->data.tel,e.tel);
printf("对电话为%s的信息进行修改成功\n",e.tel);
return 1;
}
q = q->next;
}
}
int list_delete_name(DoubleLoop L,char* name)
{
if (NULL == L)
{
printf("所给链表不合法\n");
return -1;
}
if (strlen(name) == 0)
{
printf("所给名字不能为空\n");
return -2;
}
int result = list_find_name(L,name);
if (result <= 0)
{
printf("名字为%s的联系人未找到,删除信息失败\n",name);
return -3;
}
//找到节点进行删除
//定义遍历指针,从第一个节点出发
DoubleLoop q = L->next;
while (q!= L)
{
//进行对比
if (strcmp(q->data.name,name) == 0)
{
printf("%s的信息已找到,开始进行删除\n",name);
break;
}
q = q->next;
}
//开始进行删除节点q
q->prior->next = q->next;
q->next->prior = q->prior;
free(q);
q = NULL;
L->len--;
printf("%s的信息删除成功\n",name);
}
//按位置及给定信息插入
int list_insert_pos(DoubleLoop L,int pos,datatype e)
{
if (NULL == L || pos < 0 || pos > L->len)
{
printf("所给链表不合法\n");
return -1;
}
//构造插入节点
DoubleLoop p = apply_node(e);
if (NULL == p)
{
return -2;
}
//遍历到pos-1 位置
//定义遍历指针,从头节点出发
DoubleLoop q = L;
while ( pos > 0)
{
q = q->next;
pos--;
}
printf("插入节点前一个节点数据:%d\n",q->data.id);
//以q为基准进行头插
if (q->next == L)
{
p->next = q->next;
q->next = p;
p->prior = q;
q->prior = p;
} else
{
p->next = q->next;
p->prior = q;
q->next->prior= p;
q->next = p;
}
L->len++;
printf("%d位置插入成功\n",pos);
}
int export_info_to_file(DoubleLoop L)
{
if (NULL == L)
{
printf("所给链表不合法\n");
return -1;
}
if (getLength(L)==0)
{
printf("链表中未录入信息,不能进行导出\n");
return -2;
}
//定义遍历指针,从第一个节点出发
DoubleLoop q = L->next;
//将链表中信息写入文件中
FILE *fp = fopen("./contact.txt","w");
if (NULL == fp)
{
printf("文件打开失败\n");
return -1;
}
fprintf(fp,"%s\t%s\t%s\t%s\t\n","编号","姓名","性别","电话号码");
while (q!= L)
{
//将信息保存到文件中
fprintf(fp,"%d\t\t%s\t%c\t%s\n",q->data.id,q->data.name,q->data.sex,q->data.tel);
//关闭文件
q = q->next;
}
fclose(fp);
return 0;
}
//获取链表长度
int getLength(DoubleLoop L)
{
if (NULL == L)
{
printf("所给链表不合法\n");
return -1;
}
return L->len;
}
//按照姓名将通讯录排序
void list_sort_name(DoubleLoop L)
{
//利用strcmp进行字符串比较大小,然后交换
if (NULL == L)
{
printf("所给链表不合法\n");
return;
}
if (getLength(L)==0)
{
printf("链表中未录入信息,不能进排序\n");
return;
}
if (getLength(L)==1)
{
printf("链表中只有一个元素,无需进排序\n");
return;
}
printf("链表长度:%d\n",L->len);
for (int i = 1; i < L->len; i++)
{
//定义遍历指针,从第一个节点出发
DoubleLoop q = L->next;
DoubleLoop q1 = q->next;
for (int j = 0; j < L->len- i; j++)
{
if (strcmp(q->data.name,q1->data.name) > 0)
{
swap(&(q->data),&(q1->data));
}
q = q->next;
q1 = q1->next;
}
/* code */
}
}
//统计性别
void calculate_sex(DoubleLoop L)
{
if (NULL == L)
{
printf("所给链表不合法\n");
return;
}
if (getLength(L)==0)
{
printf("链表中未录入信息,不能性别统计\n");
return;
}
int male_count = 0;
int female_count = 0;
//定义遍历指针,从第一个节点出发
DoubleLoop q = L->next;
while (q!= L)
{
if (q->data.sex == 'M')
{
male_count++;
}
if (q->data.sex == 'F')
{
female_count++;
}
q = q->next;
}
printf("男性数量:%d,女性数量:%d\n",male_count,female_count);
}
//交换函数
void swap(datatype *a,datatype *b)
{
datatype temp;
temp = *a;
*a = *b;
*b = temp;
}
main.c
#include "contact.h"
int main(int argc, char const *argv[])
{
int menu1;
char username[20];
char pwd[20];
NEXT:
while(1)
{
printf("\t\t========员工登录系统==========\n");
printf("\t\t1.注册信息\n");
printf("\t\t2.用户登录\n");
printf("\t\t0.退出\n");
printf("请输入功能选项: ");
scanf("%d",&menu1);
switch(menu1)
{
case 1:
{
for (;; )
{
printf("请输入注册账号: ");
scanf("%s",username);
printf("请输入注册密码: ");
scanf("%s",pwd);
if (strlen(pwd) < 6)
{
printf("您输入的密码不合法,请重新输入\n");
} else
{
printf("注册成功\n");
break;
}
}
//将新用户的账号和密码保存到文件中
FILE *fp = fopen("./account.txt","a+");
if (NULL == fp)
{
printf("文件打开失败\n");
return -1;
}
//将信息保存到文件中
fprintf(fp,"%s %s\n",username,pwd);
//关闭文件
fclose(fp);
}
break;
case 2:
{
char loginname[20];
char passwd[20];
printf("请输入登录账号: ");
scanf("%s",loginname);
printf("请输入登录密码: ");
scanf("%s",passwd);
//获取数据库中的账号和密码
FILE *fp = fopen("./account.txt","r");
if (NULL == fp)
{
printf("文件打开失败\n");
return -1;
}
//读取信息
while (!feof(fp))
{
fscanf(fp,"%s%s",username,pwd);
printf("username = %s\n",username);
printf("pwd = %s\n",pwd);
if (strcmp(username,loginname) == 0 && strcmp(pwd,passwd) == 0)
{
printf("登录成功\n");
DoubleLoop L = NULL;
while (1)
{
printf("二级菜单\n");
printf("\t\t1.创建模块\n");
printf("\t\t2.添加数据\n");
printf("\t\t3.查找信息\n");
printf("\t\t4.修改信息\n");
printf("\t\t5.删除信息\n");
printf("\t\t6.插入信息\n");
printf("\t\t7.展示信息\n");
printf("\t\t8.导出信息\n");
printf("\t\t9.按照姓名将通讯录排序\n");
printf("\t\t10.返回上一级\n");
printf("请输入功能选项: ");
scanf("%d",&menu1);
switch (menu1)
{
case 1:
{
//创建模块
L = list_create();
}
break;
case 2:
{
//添加数据
if (NULL == L)
{
printf("您还未创建链表,请先创建链表\n");
break;
}
printf("开始录入人员信息:\n");
char input[2];
do
{
datatype e;
printf("请输入人员编号:");
scanf("%d",&e.id);
printf("请输入人员姓名:");
scanf("%s",e.name);
//吸收垃圾字符
getchar();
printf("请输入人员性别,F:女 M:男:");
scanf("%c",&e.sex);
printf("请输入人员电话:");
scanf("%s",e.tel);
//调用尾插法插入人员数据
list_insert_tail(L,e);
printf("是否继续录入? Y/N:");
scanf("%s",input);
} while (strcmp(input,"N")!=0 && strcmp(input,"Y")==0);
}
break;
case 3:
{
if (NULL == L)
{
printf("您还未创建链表,请先创建链表\n");
break;
}
//查找信息
printf("请输入要查找的姓名:\n");
char name[20]; //定义为 char *name 直接段错误
scanf("%s",name);
list_find_name(L,name);
}
break;
case 4:
{
if (NULL == L)
{
printf("您还未创建链表,请先创建链表\n");
break;
}
//修改信息
datatype e;
printf("请输入要修改的人员姓名:");
scanf("%s",e.name);
printf("请输入要修改的人员编号:");
scanf("%d",&e.id);
//吸收垃圾字符
getchar();
printf("请输入要修改的人员性别,F:女 M:男:");
scanf("%c",&e.sex);
printf("请输入要修改的人员电话:");
scanf("%s",e.tel);
list_update_contacts(L,e);
}
break;
case 5:
{
if (NULL == L)
{
printf("您还未创建链表,请先创建链表\n");
break;
}
//删除信息
printf("请输入要删除的姓名:\n");
char name[20]; //char *name 直接段错误
scanf("%s",name);
printf("name=%s\n",name);
list_delete_name(L,name);
}
break;
case 6:
{
if (NULL == L)
{
printf("您还未创建链表,请先创建链表\n");
break;
}
//插入信息
datatype einsert;
int pos;
printf("请输入要插入的人员姓名:");
scanf("%s",einsert.name);
printf("请输入要插入的人员编号:");
scanf("%d",&einsert.id);
//吸收垃圾字符
getchar();
printf("请输入要插入的人员性别,F:女 M:男:");
scanf("%c",&einsert.sex);
printf("请输入要插入的人员电话:");
scanf("%s",einsert.tel);
printf("请输入要插入的位置:");
scanf("%d",&pos);
list_insert_pos(L,pos,einsert);
}
break;
case 7:
{
if (NULL == L)
{
printf("您还未创建链表,请先创建链表\n");
break;
}
//展示信息
list_show(L);
}
break;
case 8:
{
if (NULL == L)
{
printf("您还未创建链表,请先创建链表\n");
break;
}
//导出信息
export_info_to_file(L);
}
break;
case 9:
{
if (NULL == L)
{
printf("您还未创建链表,请先创建链表\n");
break;
}
//按照姓名将通讯录排序
list_sort_name(L);
}
break;
case 10:
{
//返回上一级
goto NEXT;
}
break;
default:
break;
}
}
}
}
printf("登录失败\n");
fclose(fp);
}
break;
case 0:
{
printf("退出系统\n");
exit(1);
}
break;
}
}
return 0;
}
}