模块:
一级菜单内容
1> 注册模块:完成用户信息的注册用于登录管理系统,将注册信息存入文件
2> 登录模块:使用输入的登录账号和密码与文件存储信息对比
3> 退出系统
二级菜单内容:
3> 创建模块create:创建链表完成对通信录的存储
4> 添加数据add:添加通信录的信息放入链表中
5> 查找信息find:可以通过姓名进行查找
6> 修改信息update:可以修改联系人信息并保存,修改联系人信息有包括了对联系人编号,姓名,性别,电话号码的分别修改,也可以同时对编号,姓名,性别,电话号码修改;
7> 删除信息delete:可根据输入的姓名进行删除
8> 插入信息insert:将给定的信息以及插入位置信息完成插入
9> 展示信息show:将通讯录的所有信息进行展示
10> 导出信息export:将通讯录信息导出到文件中
11> 按照姓名将通讯录排序
12> 返回上一级
辅助功能:
13> 初始化链表init:将链表进行初始化
14> 获取链表长度getLength:
15> 统计性别;
代码展示
main.c
#include <myhead.h>
#include "linklist.h"
int main(int argc, char const *argv[])
{
LinklistPtr L = create();
if (NULL == L)
{
return -1;
}
//后续需要使用的name的存放容器
datatype name[10];
//输入的name存放容器
datatype src[10];
int n = 1;
int res = 0;//记录是否登录成功
int pos = 0;//记录要插入的位置
while (n)
{
mune1();
int num = 0;
printf("请输入选项:\n");
scanf("%d", &num);
switch (num)
{
case 1: //注册功能
registered();
break;
case 2: //登录功能
res = login();
if (res == 0)
{
while (n == 1)
{
mune2();
printf("请输入选项:\n");
scanf("%d", &num);
switch (num)
{
case 1: //1>添加联系人
add(L);
break;
case 2: //2>查找联系人
printf("请输入你要查找的联系人的名字:");
scanf("%s", src);
strcpy(name, src);
LinklistPtr p = find_name(L, name);
printf("编号=%s\t,姓名=%s\t,性别=%s\t,电话=%s\t\n", p->data->uid, p->data->name, p->data->gender, p->data->telephone);
break;
case 3: //3>修改联系人
printf("请输入你要修改的联系人的名字:");
scanf("%s", src);
strcpy(name, src);
update(L, name);
show(L);/* */
break;
case 4: //4>删除联系人
//删除
printf("请输入你要删除的联系人的名字:");
scanf("%s", src);
strcpy(name, src);
delete_name(L, name);
show(L);
break;
case 5: //-5>插入联系人
//添加
printf("请输入你要插入的位置:");
scanf("%d",&pos);
insert(L, pos);
show(L);
break;
case 6: //6>展示通讯录
//遍历
show(L);
break;
case 7: //7>导出通讯录
//导出
export_list(L);
break;
case 8: //8>排序通讯录
//排序
sort_name(L);
show(L);
break;
case 9: //9>返回上一级
n = 2;
break;
default:
printf("非法输入\n");
break;
}
}
}
break;
case 3: //退出功能
n = 0;
break;
default:
printf("非法输入!\n");
break;
}
}
return 0;
}
linklist.c
#include "linklist.h"
//菜单1
void mune1()
{
printf("---------------1>注册---------------\n");
printf("---------------2>登录---------------\n");
printf("---------------3>退出---------------\n");
}
//菜单2
void mune2()
{
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");
}
//注册
void registered()
{
FILE *fp = NULL;
fp = fopen("./user.txt", "a+");
if (fp == NULL)
{
return;
}
//输入注册信息并写入到文件user.text中
char account[20] = {0}, pwd[20] = {0};
printf("请输入账号:");
scanf("%s", account);
printf("请输入密码:");
scanf("%s", pwd);
fputs(account, fp);
fputs("\n", fp);
fputs(pwd, fp);
fputs("\n", fp);
fclose(fp);
printf("注册成功\n");
}
//登录
int login()
{
FILE *fp = NULL;
fp = fopen("./user.txt", "r");
if (fp == NULL)
{
printf("文件打开失败\n");
return -1;
}
char account[20] = {0}, pwd[20] = {0};
char bufacc[20] = {0}, bufpwd[20] = {0};
printf("请输入账号:");
scanf("%s", account);
printf("请输入密码:");
scanf("%s", pwd);
//验证输入的信息是否和文件中的信息对等
while (1)
{
bzero(bufacc, sizeof(bufacc));
bzero(bufpwd, sizeof(bufpwd));
if (fgets(bufacc, sizeof(bufacc), fp) == NULL)
{
break;
}
//先将一行内容复制给bufacc中在将下一行内容复制给bufpwd中
fgets(bufpwd, sizeof(bufpwd), fp);
bufacc[strlen(bufacc) - 1] = '\0';
bufpwd[strlen(bufpwd) - 1] = '\0';
//如果两者相等表示登陆成功
if (strcmp(account, bufacc) == 0 && strcmp(pwd, bufpwd) == 0)
{
printf("登陆成功\n");
return 0;
}
}
printf("登陆失败\n");
fclose(fp);
return 1;
}
//链表判空
int linklist_empty(LinklistPtr L)
{
return L->next == NULL;
}
//获取链表长度getLength:
int getLength(LinklistPtr L)
{
return L->len;
}
//统计性别;
void gender(LinklistPtr L)
{
if (NULL == L||linklist_empty(L))
{
printf("统计失败\n");
return ;
}
LinklistPtr p = L->next;
int nan = 0,nv = 0;
//遍历链表性别是男nan++是女nv++
while (p != NULL)
{
if (strcmp(p->data->gender,"男")==0)
{
nan++;
}
if (strcmp(p->data->gender,"女")==0)
{
nv++;
}
p = p->next;
}
}
//创建模块create:创建链表完成对通信录的存储
LinklistPtr create()
{
LinklistPtr L = (LinklistPtr)malloc(sizeof(Linklist));
if (NULL == L)
{
printf("创建失败\n");
return NULL;
}
//初始化头结点
L->len = 0;
L->next = NULL;
L->prio = NULL;
printf("创建成功\n");
return L;
}
//创建结点
LinklistPtr apply()
{
LinklistPtr p = (LinklistPtr)malloc(sizeof(Linklist));
if (NULL == p)
{
printf("创建失败\n");
return NULL;
}
p->data = (UserPtr)malloc(sizeof(User));
if (NULL == p->data)
{
printf("分配内存失败\n");
free(p); // 释放已分配的内存
return NULL;
}
//结点的初始化
printf("请输入编号:");
scanf(" %s", p->data->uid);
printf("请输入姓名:");
scanf(" %s", p->data->name);
printf("请输入性别:");
scanf(" %s", p->data->gender);
printf("请输入电话:");
scanf(" %s", p->data->telephone);
p->next = NULL;
p->prio = NULL;
return p;
}
//添加数据add:添加通信录的信息放入链表中
int add(LinklistPtr L)
{
if (NULL == L)
{
printf("链表不合法\n");
return -1;
}
LinklistPtr p = apply();
if (NULL == p)
{
printf("添加失败\n");
return -1;
}
//链表为空时
if (linklist_empty(L))
{
p->prio = L;
L->next = p;
}
else//链表不为空时
{
p->prio = L;
p->next = L->next;
L->next->prio = p;
L->next = p;
}
L->len++;
printf("添加成功\n");
}
//查找信息find:可以通过姓名进行查找
LinklistPtr find_name(LinklistPtr L, datatype *name)
{
if (NULL == L || linklist_empty(L))
{
printf("链表非法\n");
return NULL;
}
LinklistPtr p = L->next;
while (p != NULL)
{
//p的data的name和输入的一样说明找到了,返回p
if (strcmp(p->data->name, name) == 0)
{
printf("查找成功\n");
return p;
}
p = p->next;
}
return NULL;
}
//修改信息update
int update(LinklistPtr L, datatype *name)
{
if (NULL == L || linklist_empty(L))
{
printf("链表非法\n");
return -1;
}
//先根据name找到要修改的节点
LinklistPtr p = find_name(L, name);
if (NULL == p)
{
return -1;
}
//输入要更新的数据
printf("请输入编号:");
scanf(" %s", p->data->uid);
printf("请输入姓名:");
scanf(" %s", p->data->name);
printf("请输入性别:");
scanf(" %s", p->data->gender);
printf("请输入电话:");
scanf(" %s", p->data->telephone);
printf("修改成功\n");
return 0;
}
//删除信息delete:可根据输入的姓名进行删除
int delete_name(LinklistPtr L, datatype *name)
{
if (NULL == L || linklist_empty(L))
{
printf("链表非法\n");
return -1;
}
//先根据name找到要修改的节点
LinklistPtr q = find_name(L, name);
if (NULL == q)
{
return -1;
}
//是尾节点时
if (q->next == NULL)
{
q->prio->next = NULL;
}
else //不是尾节点时
{
q->prio->next = q->next;
q->next->prio = q->prio;
}
//释放自己
free(q);
q = NULL;
printf("删除成功\n");
L->len--;
return 0;
}
// 插入信息insert:将给定的信息以及插入位置信息完成插入
int insert(LinklistPtr L, int pos)
{
if (NULL == L || pos < 0 || pos > L->len || linklist_empty(L))
{
printf("插入失败\n");
return -1;
}
LinklistPtr p = L;
//找到要插入的节点的位置
for (int i = 0; i < pos; i++)
{
p = p->next;
}
//申请节点,并添加信息
LinklistPtr q = apply();
//插入逻辑
q->next = p;//插入结点的后继指向该位置原来的结点
q->prio = p->prio;//插入结点的前继指向该位置原来的前继
p->prio->next = q;//该位置的前继结点的后继指向要插入的节点
p->prio = q;//该位置原来的前继指向出入的结点
L->len++;
printf("插入成功\n");
return 0;
}
//展示信息show:将通讯录的所有信息进行展示
int show(LinklistPtr L)
{
if (NULL == L || linklist_empty(L))
{
printf("遍历失败\n");
return -1;
}
LinklistPtr p = L->next;
while (p != NULL)
{
printf("编号=%s\t,姓名=%s\t,性别=%s\t,电话=%s\t\n", p->data->uid, p->data->name, p->data->gender, p->data->telephone);
p = p->next;
}
}
//导出信息export:将通讯录信息导出到文件中
int export_list(LinklistPtr L)
{
if (NULL == L || linklist_empty(L))
{
printf("导出失败\n");
return -1;
}
FILE *fp = NULL;
fp = fopen("./Contacts.txt", "w+");
if (NULL == fp)
{
printf("文件打开失败\n");
return -1;
}
LinklistPtr p = L->next;
//遍历链表,按一点格式写入到文件中
while (p != NULL)
{
fprintf(fp, "UID: %s, 姓名: %s, 性别: %s, 电话: %s\n", p->data->uid, p->data->name, p->data->gender, p->data->telephone);
p = p->next;
}
fclose(fp);
printf("导出成功\n");
return 0;
}
//按照姓名将通讯录排序
int sort_name(LinklistPtr L)
{
if (NULL == L || linklist_empty(L))
{
printf("排序失败\n");
return -1;
}
for (int i = 1; i < L->len; i++)
{
LinklistPtr p = L->next;
for (int j = 0; j < L->len - i; j++)
{
//把名字大的往后移动,交换两者的data结构体内容
if (strcmp(p->data->name, p->next->data->name) > 0)
{
UserPtr temp = p->data;
p->data = p->next->data;
p->next->data = temp;
}
}
}
printf("排序成功\n");
return 0;
}
//释放链表
void list_destroy(LinklistPtr L)
{
if (NULL == L)
{
printf("删除失败\n");
return;
}
//循环头删
while (!linklist_empty(L))
{
LinklistPtr p = L->next;
if (p->next == NULL)
{
//表示q为最后一个节点
p->prio->next = NULL;
}
else
{
//上传下达
p->prio->next = p->next;
p->next->prio = p->prio;
}
free(p); //释放自己
p = NULL;
}
free(L);
L = NULL;
printf("销毁成功\n");
}
linklist.h
#ifndef LINKLIST_H
#define LINKLIST_H
#include"myhead.h"
typedef char datatype;
// typedef struct admin
// {
// datatype
// };
typedef struct user
{
datatype uid[10];
datatype name[10];
datatype gender[10];
datatype telephone[11];
}User,*UserPtr;
// 结构体的创建
typedef struct Linklist
{
union
{
int len;
UserPtr data;
};
struct Linklist *prio;
struct Linklist *next;
}Linklist,*LinklistPtr;
//菜单1
void mune1();
//菜单2
void mune2();
//注册
void registered();
//登录
int login();
//链表判空
int linklist_empty(LinklistPtr L);
//获取链表长度getLength:
int getLength();
//统计性别;
void gender(LinklistPtr L);
//创建模块create:创建链表完成对通信录的存储
LinklistPtr create();
//添加数据add:添加通信录的信息放入链表中
int add(LinklistPtr L);
//查找信息find:可以通过姓名进行查找
LinklistPtr find_name(LinklistPtr L,datatype *name);
//修改信息update
int update(LinklistPtr L,datatype *name);
//删除信息delete:可根据输入的姓名进行删除
int delete_name(LinklistPtr L,datatype *name);
// 插入信息insert:将给定的信息以及插入位置信息完成插入
int insert(LinklistPtr L,int pos);
//展示信息show:将通讯录的所有信息进行展示
int show(LinklistPtr L);
//导出信息export:将通讯录信息导出到文件中
int export_list(LinklistPtr L);
//按照姓名将通讯录排序
int sort_name(LinklistPtr L);
//释放链表
void list_destroy(LinklistPtr L);
#endif
效果展示
导出的文件内容