【通讯录项目 (3 / 3)】基于顺序表的通讯录实现——通讯录项目实现

简介: 通讯录项目我们实现了大部分内容,接下来你可以自行探索,丰富功能。

通讯录项目 (3 / 3)】基于顺序表的通讯录实现——通讯录项目实现

前言

前两章我们已经知道顺序表的功能并完成了功能实现,下面我们将实现通讯录的以下功能:

1 项目预备工作

1.1 多文件处理

首先我们要对所用文件进行分类管理,以便后续操作。

我们将要在顺序表的基础上增加“contact.h”头文件和“contact.c”功能文件

注意头文件的正确引用

如下

请仔细检查,这是完成较大项目的基础。不同文件管理不同内容,方便快捷,效率高。

1.2 联系人数据管理

接下来是联系人的数据管理,我们需要改变原本顺序表的“SLDataType”为一个新类型。*我们可以想到联系人的信息不一,所以我们使用结构体来管理数据。

#define NAME_MAX 100
#define SEX_MAX 4
#define TEL_MAX 20
#define ADDR_MAX 200

//前置声明
typedef struct SeqList  contact;

//用户数据
typedef struct PersonInfo
{
  char name[NAME_MAX];
  char sex[SEX_MAX];
  int age;
  char tel[TEL_MAX];
  char addr[ADDR_MAX];
}PeoInfo;

我们用宏定义常量,方便后续查看修改。这里我设置了姓名 性别 年龄 号码 地址五种信息。代码中“前置声明”是为了避免后续引用出现问题。我们通过“typedef”进行重命名,方便后续书写代码。

2 功能实现

上面将我们的准备工作进行完毕,下面开始实现功能。我们基于顺序表在进行操作。如有不理解的地方请参考【通讯录项目 (2 / 3)】,下面不对 顺序表功能 进行详细说明

我们会使用顺序表大多数功能,请理解顺序表的功能在进行阅读。

2.1 初始化通讯录

“初始化”只需要简单的引用顺序表的初始化即可。

void InitContact(contact* con)
{
  SLInit(con);
}
void SLInit(SL* ps)
{
  assert(ps);//断言判断是否为空
  ps->a = NULL;//将初始地址改为空
  ps->size = ps->capacity = 0;//容量与大小定为空
}

这样就实现了初始化,与初始化顺序表一致。

2.2 添加联系人

添加联系人也非常简单,只需要依次输入数据,在进行顺序表的插入即可。

void AddContact(contact* con)
{
  assert(con);
  PeoInfo info;
  printf("请输入联系人姓名:\n");
  scanf("%s", info.name);
  printf("请输入联系人的性别:\n");
  scanf("%s", info.sex);
  printf("请输入联系人的年龄:\n");
  scanf("%d", &info.age); //这里需要取地址,因为age是int类型,其余为数组
  printf("请输入联系人的电话:\n");
  scanf("%s", info.tel);
  printf("请输入联系人的住址:\n");
  scanf("%s", info.addr);

  SLPushBack(con,info);
  printf("添加成功\n");
void SLPushBack(SL* ps, SLDataType x)
{
  assert(ps);
  SLCheckCapacity(ps);
  ps->a[ps->size++] = x;

这样就进行了数据的加入。

2.3 删除联系人

删除联系人依然使用顺序表的删除功能。这里需要一个"查找联系人"的功能。需要通过一个信息来查找联系人是否存在。

2.3.1 查找目标

我们输入一个信息,来进行遍历查找联系人。返回目标的偏移值。

//查找联系人
int findname(contact* con, char name[NAME_MAX])
{
  assert(con);
  for (int i = 0; i < con->size; i++)
  {
    if (strcmp(con->a[i].name, name) == 0)
    {
      return i;
    }   
  }
  return -1;
}
2.3.2 删除联系人

同样使用顺序表的删除功能来实现,通过“查找联系人”返回的偏移值来进行定位

void DelContact(contact* con) 
{
  assert(con);
  char find[NAME_MAX] = { 0 };
  printf("请输入你想删除的联系人姓名:> \n");
  scanf("%s",find);
  int ret = findname(con, find);
  if (ret < 0)
  {
    printf("未找到该联系人\n");
  }
  else
    SLErase(con, ret);
}
void SLErase(SL*ps,int pos)
{                                                                                          
  assert(ps);
  if (pos >= 0 && pos < ps->size)
  {
    for (int i = pos; i < ps->size - 1; i++)
    {
      ps->a[i] = ps->a[i + 1];//a[size-2]=a[size-1]模拟最后一次查找
    }
    ps->size--;
  }
  else
    assert(pos);
}

这样通过覆盖就完成了删除功能。

2.4 展示通讯录

展示通讯录的功能是对顺序表展示的扩展。

void ShowContact(contact* pcon) {
  //打印通讯录所有的数据
  //先打印表头文字
  assert(pcon);
  printf("%s %s %s %s %s\n", "姓名", "性别", "年龄", "电话", "住址");
  for (int i = 0; i < pcon->size; i++)
  {
    printf("%-4s %-4s %-4d %-11s %-4s\n",
      pcon->a[i].name,
      pcon->a[i].sex,
      pcon->a[i].age,
      pcon->a[i].tel,
      pcon->a[i].addr
    );
  }
}

只需遍历顺序表,并打印联系人数据即可。

注意换行符,与打印格式让界面更加美观。

2.5 查找与修改

查找与修改操作相似,我们放在一起说明

2.5.1 查找联系人

查找联系人以上面的查找目标功能为基础,通过遍历进行查找。这里需要进行一次打印操作来展示查找结果

void FindContact(contact* con)
{
  assert(con);
  char find[NAME_MAX] = { 0 };
  printf("请输入想要查找的联系人姓名:> \n");
  scanf("%s",find);
  int ret = findname(con, find);
  if (ret < 0)
  {
    printf("未找到该联系人\n");
    
  }
  else{
    printf("找到了\n");
  printf("%s %s %s %s %s\n", "姓名", "性别", "年龄", "电话", "住址");
    printf("%-4s %-4s %-4d %-4s %-4s\n",
      con->a[ret].name,
      con->a[ret].sex,
      con->a[ret].age,
      con->a[ret].tel,
      con->a[ret].addr
    );
  }
}
2.5.2 修改联系人

修改联系人同样基于“查找目标”功能的基础,并进行一次修改操作。

oid ModifyContact(contact* con)
{
  assert(con);
  int name[NAME_MAX] = { 0 };
  printf("请输入想修改的联系人: > \n");
  scanf("%s", name);
  int ret = findname(con, name);
  //通过偏移量进行修改
  printf("请输入联系人姓名:\n");
  scanf("%s", con->a[ret].name);
  printf("请输入联系人的性别:\n");
  scanf("%s", con->a[ret].sex);
  printf("请输入联系人的年龄:\n");
  scanf("%d", &con->a[ret].age);
  printf("请输入联系人的电话:\n");
  scanf("%s", con->a[ret].tel);
  printf("请输入联系人的住址:\n");
  scanf("%s", con->a[ret].addr);
  printf("修改完成\n");
  ShowContact(con);

}

2.6 销毁通讯录

销毁功能是对储存空间的操作,通过free来实现销毁。

void DestroyContact(contact* con)
{
  assert(con);
  free(con->a);
  con->size = con->capacity = 0;
  con->a = NULL;
}

3 界面完成

上面我们已经实现了通讯录的大部分功能,还有一些额外功能没有加入,比如读取文件数据,储存到文件等。

下面我们开始完善界面内容,来把通讯录的功能进行整合。

3.1 打印菜单

这个容易实现,按照喜好设置即可,下面给予参考

void menu()
{
  printf("*************************************\n");
  printf("*********      通讯录      **********\n");
  printf("**** 1.添加联系人  2.删除联系人 *****\n");
  printf("**** 3.修改联系人  4.查找联系人 *****\n");
  printf("**** 5.查看通讯录  0.退出通讯录 *****\n");
}

效果如图

28b5fba8f0b1fc77e102f527ac054535_03bc56a5cc554a5fa4c7edf408821ee8.png

3.2 完成功能选择

通过switch语句我们可以方便的完成功能选择

int main()
{
  int op = -1;
  contact con;
  InitContact(&con);
  do {
    menu();
    printf("请选择你的操作:> \n");
    scanf("%d",&op);
    switch (op)
    {
      case 1:
        AddContact(&con);
        break;
      case 2:
        DelContact(&con);
        break;
      case 3:
        ModifyContact(&con);
        break;
      case 4:
        FindContact(&con);
        break;
      case 5:
        ShowContact(&con);
        break;
      case 0:
        printf("goodbye~\n");
        break;
      default:
        printf("输入格式有误,重新输入:> \n");
        break;
    }
  } while (op != 0);

  DestroyContact(&con);

  return 0;
}

这样我们就完成了功能选择,都是有一点点瑕疵。

3.3 界面优化

通过上面的菜单我们在进行几步操作后便会发现

界面非常冗杂混乱,如何解决呢。

我们可以通过

system("pause");
  system("cls");

这两行简单的代码便可以大大优化界面

int main()
{
  int op = -1;
  contact con;
  InitContact(&con);
  do {
    menu();
    printf("请选择你的操作:> \n");
    scanf("%d",&op);
    switch (op)
    {
      case 1:
        AddContact(&con);
        system("pause");
        system("cls");
        break;
      case 2:
        DelContact(&con);
        system("pause");
        system("cls");
        break;
      case 3:
        ModifyContact(&con);
        system("pause");
        system("cls");
        break;
      case 4:
        FindContact(&con);
        system("pause");
        system("cls");
        break;
      case 5:
        ShowContact(&con);
        system("pause");
        system("cls");
        break;
      case 0:
        printf("goodbye~\n");
        system("pause");
        system("cls");
        break;
      default:
        printf("输入格式有误,重新输入:> \n");
        system("pause");
        system("cls");
        break;
    }
  } while (op != 0);

  DestroyContact(&con);

  return 0;
}

让我们看看效果

无论进行多少操作,我们的界面依然清爽。

结语

通讯录项目我们实现了大部分内容,接下来你可以自行探索,丰富功能。

谢谢你的阅读

祝您前程似锦

相关文章
简易实现通讯录(1.0)
简易实现通讯录(1.0)
46 0
简易实现通讯录(2.0)
简易实现通讯录(2.0)
47 0
|
30天前
通讯录项目
通讯录项目
12 1
|
5月前
|
C++
C++案例简单通讯录
C++案例简单通讯录
26.通讯录的实现
26.通讯录的实现
|
6月前
|
C语言
【通讯录项目 (2 / 3)】基于顺序表的通讯录实现——顺序表功能实现
顺序表的功能我们已经实现,我们使用的是最简单的顺序表,所以整个过程看起来没有困难。在下一篇文章中我们将进行通讯录的实现。 在通讯录里,顺序表的类型不在是简单的" int ",而是结构体类型。 下面给出通讯录的基本功能供大家参考预习。
47 0
|
6月前
|
存储 算法
|
存储
通讯录实现上
通讯录实现上
通讯录实现上
|
C语言
【纯C实现简易通讯录】
【纯C实现简易通讯录】
58 0
|
6月前
通讯录实现
通讯录实现
44 0