华清数据结果项目(24-7-27):基于链表的通信录管理意义:对于一个通信录来说,要管理联系人的编号,姓名,性别,电话。开发其系统主要为了帮助用户提高通讯录有管理效率,节约资源,提高信息的精确度

模块:
一级菜单内容
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

效果展示

导出的文件内容

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值