C语言实现通讯录管理系统(超详细!-实现动态扩容,文件保存!)

简介: C语言实现通讯录管理系统(超详细!-实现动态扩容,文件保存!)

一、总体思路

       需要什么功能?->1、添加联系人(同时将之前存储号的通讯录文件加载进来) 2、删除联系人 3、查找联系人 4、修改联系人 5、显示所有联系人 6、排序联系人->按什么排序?->年龄?名字? 7、以文件形式保存  8、退出系统(释放空间)

       需要存储什么信息?->1、姓名 2、年龄 3、性别 4、电话号码 5、地址

       要实现的是静态的?(不可扩容)还是动态的?(自动扩容)->动态!

确定基本框架如下:

enum option//功能确定,用于后续Switch
{
  Exit,
  Add,
  Del,
  Search,
  Modify,
  Show,
  Sort
};
typedef struct tp//存储信息
{
  char name[10];
  int age;
  char sex[SEX];
  char telp[TELP];
  char addr[ADDR];
}tp;
typedef struct Contact//动态储存,方便扩容
{
  tp* data;
  int sz;
  int capacity;
}Contact;

  写出函数接口以确定整体的作用->确定以结构体指针的形式传参数

如下:

void InitContact(Contact* p);//初始化
void AddContact(Contact* p);//添加
void ShowContact(Contact* p);//显示
void DelContact(Contact* p);//删除
void SearchContact(Contact* p);//查找
void ModifyContact(Contact* p);//修改
void SortContact(Contact* p);//排序
void DestroyContact(Contact* p);//退出销毁
void SaveContact(Contact* p);//保存文件

 接下来就是写下总体结构以及系统界面->确定以Switch函数来构造

如下:

void menu()
{
  printf("**************************************\n");
  printf("*****1、add   *********2、del   ******\n");
  printf("*****3、search*********4、modify******\n");
  printf("*****5、show  *********6、sort  ******\n");
  printf("*****0、exit  *********         ******\n");
  printf("**************************************\n");
  printf("请选择>");
}
void text()
{
  int input = 0;
  Contact p;
  InitContact(&p);
  do
  {
    menu();
    scanf("%d", &input);
    system("cls");
    switch (input)
    {
    case Add:
      AddContact(&p);
      break;
    case Del:
      DelContact(&p);
      break;
    case Search:
      SearchContact(&p);
      break;
    case Modify:
      ModifyContact(&p);
      break;
    case Show:
      ShowContact(&p);
      break;
    case Sort:
      SortContact(&p);
      //namesort1(&p);
      break;
    case Exit:
      SaveContact(&p);
      DestroyContact(&p);
      printf("退出成功!\n");
      break;
    default:
      printf("输入错误,请重新输入!\n");
      break;
    }
  } while (input);
}
int main()
{
  text();
  return 0;
}

二、各个部分函数实现

1、初始化  InitContact(Contact* p)

void InitContact(Contact* p)
{
  assert(p);
  p->data = (tp*)malloc(sizeof(tp) * TELnum);//calloc
  if (p->data == NULL)
  {
    perror("malloc");
    return;
  }
  memset(p->data, 0, sizeof(p->data));
  p->sz = 0;
  p->capacity = TELnum;
  //文件中保存的信息加载到通讯录中
  LoadContact(p);
}

2、增加联系人 AddContact(Contact* p)

int CheckCapacity(Contact* pc)
{
  if (pc->sz == pc->capacity)
  {
    tp* ptr = (tp*)realloc(pc->data, (pc->capacity + INC)*sizeof(tp));
    if (ptr == NULL)
    {
      perror("CheckCapacity");
      return 0;
    }
    else
    {
      pc->data = ptr;
      pc->capacity += INC;
      printf("增容成功\n");
      return 1;
    }
  }
  return 1;
}
void AddContact(Contact* p)
{
  assert(p);
  if (0==CheckCapacity(&p))
  {
    printf("通讯录已满!\n");
    //EnContact(&p);
  }
  printf("\n请输入姓名>");
  scanf("%s",p->data[p->sz].name);
  printf("\n请输入年龄>");
  scanf("%d", &p->data[p->sz].age);
  printf("\n请输入性别>");
  scanf("%s", p->data[p->sz].sex);
  printf("\n请输入电话号码>");
  scanf("%s", p->data[p->sz].telp);
  printf("\n请输入地址>");
  scanf("%s", p->data[p->sz].addr);
  printf("在通讯录中成功添加%s的信息!\n", p->data[p->sz].name);
  p->sz++;
}

3、删除联系人 DelContact(Contact* p)

void DelContact(Contact* p)
{
  assert(p);
  int flag = 0, de = 0;
  if (p->sz == 0)
  {
    printf("通讯录为空!无法删除!\n");
    return;
  }
  printf("输入删除信息的姓名>");
  char arr[20]="0";
  scanf("%s",&arr);
  for (int i = 0; i < p->sz; i++)
  {
    if (strcmp(p->data[i].name, arr) == 0)//按照名字删除
    {
      flag = 1;
      de = i;
      break;
    }
  }
  if (flag == 1)
  {
    for (int j = de; j < p->sz - 1; j++)
    {
      p->data[j] = p->data[j + 1];
    }
    p->sz--;
    printf("成功删除!\n");
  }
  if (flag == 0)
    printf("通讯录中未找到该联系人!\n");
}

4、查找联系人信息 SearchContact(Contact* p)

void SearchContact(Contact* p)
{
  assert(p);
  if (p->sz == 0)
  {
    printf("通讯录为空,无法查找!\n");
      return;
  }
  printf("输入查找人的姓名>");
  char arr[20]="0";
  scanf("%s", arr);
  for (int i = 0; i < p->sz; i++)
  {
    if (strcmp(p->data[i].name, arr) == 0)//通过姓名查找
    {
      printf("%-10s\t%-4s\t%-5s\t%-12s\t%-30s\n", "名字", "年龄", "性别", "电话", "地址");
      printf("%-10s\t%-4d\t%-5s\t%-12s\t%-30s\n",
        p->data[i].name,
        p->data[i].age,
        p->data[i].sex,
        p->data[i].telp,
        p->data[i].addr);
      return;
    }
  }
  printf("未找到该联系人!\n");
}
2. vo

5、修改联系人信息 ModifyContact(Contact* p)

void ModifyContact(Contact* p)
{
  assert(p);
  if (p->sz == 0)
  {
    printf("通讯录为空,无法查找!\n");
    return;
  }
  printf("输入要修改人的姓名>");
  char arr[20]="0";
  scanf("%s", &arr);
  for (int i = 0; i < p->sz; i++)
  {
    if (strcmp(p->data[i].name, arr) == 0)//通过姓名修改
    {
      printf("\n请输入姓名>");
      scanf("%s", p->data[i].name);
      printf("\n请输入年龄>");
      scanf("%d", &p->data[i].age);
      printf("\n请输入性别>");
      scanf("%s", p->data[i].sex);
      printf("\n请输入电话号码>");
      scanf("%s", p->data[i].telp);
      printf("\n请输入地址>");
      scanf("%s", p->data[i].addr);
      printf("在通讯录中成功修改%s的信息!\n", p->data[i].name);
      return;
    }
  }
  printf("未找到要修改人%s的信息!", arr);
}

6、排序联系人->按姓名?按年龄? SortContact(Contact* p)

void SortContact(Contact* p)//懒得分装了0.0
{
  assert(p);
  if (p->sz == 0)
  {
    printf("\n通讯录为空,无法排序!!!\n");
    return;
  }
  printf("请选择排序的形式>");
  printf("\n*******************************");//提升菜单
  printf("\n**1、按名字排序  2、按年龄排序**");
  printf("\n*******************************\n");
  int ret = 0;
  scanf("%d", &ret);
  if(ret==1)
  {
    printf("选择升序或降序>");
    printf("\n**1、升**2、降**\n");
    int re = 0;
    Contact* pc = p;
    scanf("%d", &re);
    if (re == 1)//名字升序
    {
      int i = 0;
      int j = 0;
      tp tmp;
      for (i = 0; i < p->sz - 1; i++)
      {
        int flag = 1;
        for (j = 0; j < p->sz - i - 1; j++)
        {
          if (strcmp(p->data[j].name, p->data[j + 1].name) > 0)
          {
            tmp = p->data[j];
            p->data[j] = p->data[j + 1];
            p->data[j + 1] = tmp;
            flag = 0;
          }
        }
        if (flag == 1)
        {
          return;
        }
      }
      printf("\n排序成功\n");
      //namesort1(&pc);
    }
    else if (re == 2)//名字降序
    {
      int i = 0;
      int j = 0;
      tp tmp;
      for (i = 0; i < p->sz - 1; i++)
      {
        int flag = 1;
        for (j = 0; j < p->sz - i - 1; j++)
        {
          if (strcmp(p->data[j].name, p->data[j + 1].name) < 0)
          {
            tmp = p->data[j];
            p->data[j] = p->data[j + 1];
            p->data[j + 1] = tmp;
            flag = 0;
          }
        }
        if (flag == 1)
        {
          return;
        }
      }
      printf("\n排序成功\n");
      //namesort2(&pc);
    }
    else
    {
      printf("\n输入错误!\n");
    }
    //sort2(&p);
  }
  else if (ret == 2)
  {
    printf("选择升序或降序>");
    printf("\n**1、升**2、降**\n");
    int re = 0;
    scanf("%d", &re);
    switch (re)
    {
    case 1://年龄升序
      for (int i = 0; i < p->sz - 1; i++)
      {
        for (int j = 0; j < p->sz - 1 - i; j++)
        {
          if (p->data[j].age > p->data[j + 1].age)
          {
            tp temp = p->data[j];
            p->data[j] = p->data[j + 1];
            p->data[j + 1] = temp;
          }
        }
      }
      printf("\n排序成功!\n");
      break;
    case 2://年龄降序
      for (int i = 0; i < p->sz - 1; i++)
      {
        for (int j = 0; j < p->sz - 1 - i; j++)
        {
          if (p->data[j].age < p->data[j + 1].age)
          {
            tp temp = p->data[j];
            p->data[j] = p->data[j + 1];
            p->data[j + 1] = temp;
          }
        }
      }
      printf("\n排序成功!\n");
      break;
    default:
      printf("\n输入错误!\n");
      break;
    }
  }
  else
  {
    printf("\n输入错误!\n");
  }
}

7、 退出前保存文件 SaveContact(Contact* p)

void LoadContact(Contact* pc)//这里为上面第一小电中的加载函数
{
  //打开文件
  FILE* pf = fopen("contact.dat", "rb");
  if (pf == NULL)
  {
    perror("LoadContact");
    return;
  }
  //读文件
  tp tmp = { 0 };
  while (fread(&tmp, sizeof(tp), 1, pf))
  {
    if (0 == CheckCapacity(pc))
      return;
    pc->data[pc->sz] = tmp;
    pc->sz++;
  }
  //关闭文件
  fclose(pf);
  pf = NULL;
}
void SaveContact(Contact* pc)
{
  FILE* pf = fopen("contact.dat", "wb");
  if (pf == NULL)
  {
    perror("SaveContact");
    return;
  }
  //写数据
  int i = 0;
  for (i = 0; i < pc->sz; i++)
  {
    fwrite(pc->data + i, sizeof(tp), 1, pf);
  }
  //关闭文件
  fclose(pf);
  pf = NULL;
}

8、 退出销毁(释放内存)DestroyContact(Contact* p)

void DestroyContact(Contact* p)
{
  free(p->data);
  p->data = NULL;
  p->capacity = 0;
  p->sz = 0;
}

三、总体代码

1、rel.h

#pragma once
#define NAME 20
#define SEX 5
#define TELP 12
#define ADDR 30
#define TELnum 20
#define INC 20
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<assert.h>
enum option
{
  Exit,
  Add,
  Del,
  Search,
  Modify,
  Show,
  Sort
};
typedef struct tp
{
  char name[10];
  int age;
  char sex[SEX];
  char telp[TELP];
  char addr[ADDR];
}tp;
typedef struct Contact
{
  tp* data;
  int sz;
  int capacity;
}Contact;
void InitContact(Contact* p);//初始化
void AddContact(Contact* p);//添加
void ShowContact(Contact* p);//显示
void DelContact(Contact* p);//删除
void SearchContact(Contact* p);//查找
void ModifyContact(Contact* p);//修改
void SortContact(Contact* p);//排序
void DestroyContact(Contact* p);//退出销毁
void SaveContact(Contact* p);//保存文件

2、rel.c

#define _CRT_SECURE_NO_WARNINGS 01
#include"rel.h"
int CheckCapacity(Contact* pc);
void LoadContact(Contact* pc)
{
  //打开文件
  FILE* pf = fopen("contact.dat", "rb");
  if (pf == NULL)
  {
    perror("LoadContact");
    return;
  }
  //读文件
  tp tmp = { 0 };
  while (fread(&tmp, sizeof(tp), 1, pf))
  {
    if (0 == CheckCapacity(pc))
      return;
    pc->data[pc->sz] = tmp;
    pc->sz++;
  }
  //关闭文件
  fclose(pf);
  pf = NULL;
}
void InitContact(Contact* p)
{
  assert(p);
  p->data = (tp*)malloc(sizeof(tp) * TELnum);//calloc
  if (p->data == NULL)
  {
    perror("malloc");
    return;
  }
  memset(p->data, 0, sizeof(p->data));
  p->sz = 0;
  p->capacity = TELnum;
  //文件中保存的信息加载到通讯录中
  LoadContact(p);
}
int CheckCapacity(Contact* pc)
{
  if (pc->sz == pc->capacity)
  {
    tp* ptr = (tp*)realloc(pc->data, (pc->capacity + INC)*sizeof(tp));
    if (ptr == NULL)
    {
      perror("CheckCapacity");
      return 0;
    }
    else
    {
      pc->data = ptr;
      pc->capacity += INC;
      printf("增容成功\n");
      return 1;
    }
  }
  return 1;
}
void AddContact(Contact* p)
{
  assert(p);
  if (0==CheckCapacity(&p))
  {
    printf("通讯录已满!\n");
    //EnContact(&p);
  }
  printf("\n请输入姓名>");
  scanf("%s",p->data[p->sz].name);
  printf("\n请输入年龄>");
  scanf("%d", &p->data[p->sz].age);
  printf("\n请输入性别>");
  scanf("%s", p->data[p->sz].sex);
  printf("\n请输入电话号码>");
  scanf("%s", p->data[p->sz].telp);
  printf("\n请输入地址>");
  scanf("%s", p->data[p->sz].addr);
  printf("在通讯录中成功添加%s的信息!\n", p->data[p->sz].name);
  p->sz++;
}
void ShowContact(Contact* p)
{
  assert(p);
  int i = 0;
  if (p->sz == 0)
  {
    printf("通讯录为空!\n");
    return;
  }
  printf("%-10s\t%-4s\t%-5s\t%-12s\t%-30s\n", "名字", "年龄", "性别", "电话", "地址");
  while (i < p->sz)
  {
    printf("%-10s\t%-4d\t%-5s\t%-12s\t%-30s\n",
      p->data[i].name,
      p->data[i].age,
      p->data[i].sex,
      p->data[i].telp,
      p->data[i].addr);
    i++;
  }
}
void DelContact(Contact* p)
{
  assert(p);
  int flag = 0, de = 0;
  if (p->sz == 0)
  {
    printf("通讯录为空!无法删除!\n");
    return;
  }
  printf("输入删除信息的姓名>");
  char arr[20]="0";
  scanf("%s",&arr);
  for (int i = 0; i < p->sz; i++)
  {
    if (strcmp(p->data[i].name, arr) == 0)//按照名字删除
    {
      flag = 1;
      de = i;
      break;
    }
  }
  if (flag == 1)
  {
    for (int j = de; j < p->sz - 1; j++)
    {
      p->data[j] = p->data[j + 1];
    }
    p->sz--;
    printf("成功删除!\n");
  }
  if (flag == 0)
    printf("通讯录中未找到该联系人!\n");
}
void SearchContact(Contact* p)
{
  assert(p);
  if (p->sz == 0)
  {
    printf("通讯录为空,无法查找!\n");
      return;
  }
  printf("输入查找人的姓名>");
  char arr[20]="0";
  scanf("%s", arr);
  for (int i = 0; i < p->sz; i++)
  {
    if (strcmp(p->data[i].name, arr) == 0)//通过姓名查找
    {
      printf("%-10s\t%-4s\t%-5s\t%-12s\t%-30s\n", "名字", "年龄", "性别", "电话", "地址");
      printf("%-10s\t%-4d\t%-5s\t%-12s\t%-30s\n",
        p->data[i].name,
        p->data[i].age,
        p->data[i].sex,
        p->data[i].telp,
        p->data[i].addr);
      return;
    }
  }
  printf("未找到该联系人!\n");
}
void ModifyContact(Contact* p)
{
  assert(p);
  if (p->sz == 0)
  {
    printf("通讯录为空,无法查找!\n");
    return;
  }
  printf("输入要修改人的姓名>");
  char arr[20]="0";
  scanf("%s", &arr);
  for (int i = 0; i < p->sz; i++)
  {
    if (strcmp(p->data[i].name, arr) == 0)//通过姓名修改
    {
      printf("\n请输入姓名>");
      scanf("%s", p->data[i].name);
      printf("\n请输入年龄>");
      scanf("%d", &p->data[i].age);
      printf("\n请输入性别>");
      scanf("%s", p->data[i].sex);
      printf("\n请输入电话号码>");
      scanf("%s", p->data[i].telp);
      printf("\n请输入地址>");
      scanf("%s", p->data[i].addr);
      printf("在通讯录中成功修改%s的信息!\n", p->data[i].name);
      return;
    }
  }
  printf("未找到要修改人%s的信息!", arr);
}
void SortContact(Contact* p)
{
  assert(p);
  if (p->sz == 0)
  {
    printf("\n通讯录为空,无法排序!!!\n");
    return;
  }
  printf("请选择排序的形式>");
  printf("\n*******************************");//提升菜单
  printf("\n**1、按名字排序  2、按年龄排序**");
  printf("\n*******************************\n");
  int ret = 0;
  scanf("%d", &ret);
  if(ret==1)
  {
    printf("选择升序或降序>");
    printf("\n**1、升**2、降**\n");
    int re = 0;
    Contact* pc = p;
    scanf("%d", &re);
    if (re == 1)//名字升序
    {
      int i = 0;
      int j = 0;
      tp tmp;
      for (i = 0; i < p->sz - 1; i++)
      {
        int flag = 1;
        for (j = 0; j < p->sz - i - 1; j++)
        {
          if (strcmp(p->data[j].name, p->data[j + 1].name) > 0)
          {
            tmp = p->data[j];
            p->data[j] = p->data[j + 1];
            p->data[j + 1] = tmp;
            flag = 0;
          }
        }
        if (flag == 1)
        {
          return;
        }
      }
      printf("\n排序成功\n");
      //namesort1(&pc);
    }
    else if (re == 2)//名字降序
    {
      int i = 0;
      int j = 0;
      tp tmp;
      for (i = 0; i < p->sz - 1; i++)
      {
        int flag = 1;
        for (j = 0; j < p->sz - i - 1; j++)
        {
          if (strcmp(p->data[j].name, p->data[j + 1].name) < 0)
          {
            tmp = p->data[j];
            p->data[j] = p->data[j + 1];
            p->data[j + 1] = tmp;
            flag = 0;
          }
        }
        if (flag == 1)
        {
          return;
        }
      }
      printf("\n排序成功\n");
      //namesort2(&pc);
    }
    else
    {
      printf("\n输入错误!\n");
    }
    //sort2(&p);
  }
  else if (ret == 2)
  {
    printf("选择升序或降序>");
    printf("\n**1、升**2、降**\n");
    int re = 0;
    scanf("%d", &re);
    switch (re)
    {
    case 1://年龄升序
      for (int i = 0; i < p->sz - 1; i++)
      {
        for (int j = 0; j < p->sz - 1 - i; j++)
        {
          if (p->data[j].age > p->data[j + 1].age)
          {
            tp temp = p->data[j];
            p->data[j] = p->data[j + 1];
            p->data[j + 1] = temp;
          }
        }
      }
      printf("\n排序成功!\n");
      break;
    case 2://年龄降序
      for (int i = 0; i < p->sz - 1; i++)
      {
        for (int j = 0; j < p->sz - 1 - i; j++)
        {
          if (p->data[j].age < p->data[j + 1].age)
          {
            tp temp = p->data[j];
            p->data[j] = p->data[j + 1];
            p->data[j + 1] = temp;
          }
        }
      }
      printf("\n排序成功!\n");
      break;
    default:
      printf("\n输入错误!\n");
      break;
    }
  }
  else
  {
    printf("\n输入错误!\n");
  }
}
void DestroyContact(Contact* p)
{
  free(p->data);
  p->data = NULL;
  p->capacity = 0;
  p->sz = 0;
}
void SaveContact(Contact* pc)
{
  FILE* pf = fopen("contact.dat", "wb");
  if (pf == NULL)
  {
    perror("SaveContact");
    return;
  }
  //写数据
  int i = 0;
  for (i = 0; i < pc->sz; i++)
  {
    fwrite(pc->data + i, sizeof(tp), 1, pf);
  }
  //关闭文件
  fclose(pf);
  pf = NULL;
}

3、text.c

#define _CRT_SECURE_NO_WARNINGS 01
#include"rel.h"
void menu()
{
  printf("**************************************\n");
  printf("*****1、add   *********2、del   ******\n");
  printf("*****3、search*********4、modify******\n");
  printf("*****5、show  *********6、sort  ******\n");
  printf("*****0、exit  *********         ******\n");
  printf("**************************************\n");
  printf("请选择>");
}
void text()
{
  int input = 0;
  Contact p;
  InitContact(&p);
  do
  {
    menu();
    scanf("%d", &input);
    system("cls");
    switch (input)
    {
    case Add:
      AddContact(&p);
      break;
    case Del:
      DelContact(&p);
      break;
    case Search:
      SearchContact(&p);
      break;
    case Modify:
      ModifyContact(&p);
      break;
    case Show:
      ShowContact(&p);
      break;
    case Sort:
      SortContact(&p);
      //namesort1(&p);
      break;
    case Exit:
      SaveContact(&p);
      DestroyContact(&p);
      printf("退出成功!\n");
      break;
    default:
      printf("输入错误,请重新输入!\n");
      break;
    }
  } while (input);
}
int main()
{
  text();
  return 0;
}
相关文章
|
5天前
|
Linux C语言
C语言获取文件长度
C语言获取文件长度
|
5天前
|
编译器 开发工具 C语言
【C语言】第一回(源(.c)文件怎么生成可执程序(.exe)文件)
【C语言】第一回(源(.c)文件怎么生成可执程序(.exe)文件)
|
5天前
|
存储 C语言 C++
【C语言】文件与文件操作
前言:我们通过学习的技术可以完成计算与字符串处理,但程序结束之后就都消失了,这样岂不可惜。我们通过文件与数据持久化保存相关的基础知识。
12 0
|
5天前
|
存储 C语言
C语言进阶第十课 --------文件的操作-2
C语言进阶第十课 --------文件的操作
|
5天前
|
存储 编译器 C语言
C语言进阶第十课 --------文件的操作-1
C语言进阶第十课 --------文件的操作
|
5天前
|
C语言
C语言进阶第八课 --------通讯录的实现
C语言进阶第八课 --------通讯录的实现
|
5天前
|
存储 算法 C语言
C语言进阶:顺序表(数据结构基础) (以通讯录项目为代码练习)
C语言进阶:顺序表(数据结构基础) (以通讯录项目为代码练习)
|
5天前
|
存储 自然语言处理 编译器
C语言:编译和链接(从.c文件到输出结果的过程)
C语言:编译和链接(从.c文件到输出结果的过程)
|
5天前
|
存储 C语言
C语言动态存储方式与静态存储方式
C语言动态存储方式与静态存储方式
11 0
|
5天前
通讯录(C语言版)
通讯录(C语言版)