中级版本较初级版本增加了动态内存分配的功能

以下分为contast.h、test.c、contast.c三个部分实现


一、contast.h


#define _CRT_SECURE_NO_WARNINGS

#include<stdio.h>

#include<string.h>

#include<stdlib.h>


#define Size_name 20

#define Size_sex 4

#define Size_tel 13

#define Size_address 20

#define MAX 2000

#define Init_capacity 3


enum Option

{

Exit,//0

Add,//1

Del,

Modify,

Search,

Sort,

Show

};

typedef struct PeoInfor

{

char Name[Size_name];

int Age;

char Sex[Size_sex];

char Tel[Size_tel];

char Address[Size_address];

}PeoInfor;//第一个结构体用来存放联系人的基本信息


typedef struct Contact

{

PeoInfor *data;//指向动态开辟的内存

int size;//记录当前已有的元素个数

int capacity;//当前通讯录的最大容量

}Contact;//第二个结构体包含了第一个结构体还增加了存储联系人的个数


void InitContact(Contact* ps);

void AddContact(Contact* ps);

void ShowContact(Contact* ps);

void DelContact(Contact* ps);

void ModifyContact(Contact* ps);

void SearchContact(const Contact* ps);

void SortContact(Contact* ps);

void DestroyContact(Contact* ps);



二、test.c

#define _CRT_SECURE_NO_WARNINGS

#include"contact.h"

void menu()

{

printf("********************************\n");

printf("*****   1.Add     2.Del    *****\n");

printf("*****   3.Modify  4.Search *****\n");

printf("*****   5.Sort    6.Show   *****\n");

printf("*****         0.Exit       *****\n");

printf("********************************\n");

}


void test()

{

int input = 0;

//定义一个结构体存放用户的信息

Contact con;

//动态分配内存的初始化

InitContact(&con);

do

{

 menu();

 printf("请选择:");

 scanf("%d", &input);

 switch (input)

 {

 case Add:

  AddContact(&con);

  break;

 case Del:

  DelContact(&con);

  break;

 case Modify:

  ModifyContact(&con);

  break;

 case Search:

  SearchContact(&con);

  break;

 case Sort:

  SortContact(&con);

  break;

 case Show:

  ShowContact(&con);

  break;

 case Exit:

  DestroyContact(&con);//销毁通讯录,释放动态开辟的内存

  printf("退出通讯录");

  break;

 default:

  printf("输入错误,请重新输入\n");

  break;

 }

} while (input);

}


int main()

{

test();

return 0;

}



三、contact.c

#define _CRT_SECURE_NO_WARNINGS

#include"contact.h"


void InitContact(Contact* ps)

{

ps->data = (PeoInfor* )malloc(Init_capacity * sizeof(PeoInfor));

if (ps->data == NULL)

{

 return;

}

ps->size = 0;//初始化数据,使通讯录开始具有3个联系人的空间,之后每次动态开辟2个联系人的空间

ps->capacity = Init_capacity;

}


void Checkcapacity(Contact* ps)

{

if (ps->size == ps->capacity)

{

 PeoInfor* ptr = realloc(ps->data, (ps->capacity + 2) * sizeof(PeoInfor));

 if (ptr != NULL)

 {

  ps->data = ptr;

  ps->capacity += 2;

  printf("增容成功\n");

 }

 else

 {

  printf("增容失败\n");

 }

}

}

void AddContact(Contact* ps)

{

Checkcapacity(ps);//检查动态分配的内存是否够用

printf("请输入名字:");

scanf("%s", ps->data[ps->size].Name);

printf("请输入年龄:");

scanf("%d", &(ps->data[ps->size].Age));

printf("请输入性别:");

scanf("%s", ps->data[ps->size].Sex);

printf("请输入电话:");

scanf("%s", ps->data[ps->size].Tel);

printf("请输入住址:");

scanf("%s", ps->data[ps->size].Address);

printf("添加成功\n");

ps->size++;//通讯录人数加一

}


void ShowContact(Contact* ps)

{

int i = 0;

if (ps->size == 0)

{

 printf("通讯录为空\n");

}

else

{

 printf("%-20s\t%-4s\t%-4s\t%-13s\t%-20s\n", "姓名", "年龄", "性别", "电话", "地址");

 for (i = 0; i < ps->size; i++)

 {

  printf("%-20s\t%-4d\t%-4s\t%-13s\t%-20s\n", ps->data[i].Name,

             ps->data[i].Age,

             ps->data[i].Sex,

             ps->data[i].Tel,

             ps->data[i].Address);

 }

}

}


void DelContact(Contact* ps)

{

 int i = 0;

 int j = 0;

 char name[Size_name];

 printf("请输入需要删除联系人的姓名:");

 scanf("%s", name);

 //查找要删除联系人的下标

 for (i = 0; i < ps->size; i++)

 {

  if (0 == strcmp(ps->data[i].Name, name))

  {

   break;

  }

 }

 //找到之后从后往前替换数据

 if (i == ps->size)

 {

  printf("要删除的人不存在\n");

 }

 else

 {

 for (j = i; j < ps->size - 1; j++)

 {

  ps->data[j] = ps->data[j + 1];

 }

 ps->size--;

 }

}


void ModifyContact(Contact* ps)

{

char name[Size_name];

printf("请输入要修改联系人的姓名:");

scanf("%s", name);

//查找要修改人的位置

int i = 0;

for (i = 0; i < ps->size; i++)

{

 if (0 == strcmp(ps->data[i].Name, name))

 {

  break;

 }

}

if (i == ps->size)

{

 printf("要修改的人不存在\n");

}

else

{

 printf("请输入要更改的姓名:");

 scanf("%s", ps->data[i].Name);

 printf("请输入要更改的年龄:");

 scanf("%d", &(ps->data[i].Age));

 printf("请输入要更改的性别:");

 scanf("%s", ps->data[i].Sex);

 printf("请输入要更改的电话:");

 scanf("%s", ps->data[i].Tel);

 printf("请输入要更改的地址:");

 scanf("%s", ps->data[i].Address);

 printf("修改成功\n");

}

}


void SearchContact(const Contact* ps)

{

char name[Size_name];

printf("请输入要查找联系人的姓名:");

scanf("%s", name);

//查找被查找人的位置

int i = 0;

for (i = 0; i < ps->size; i++)

{

 if (0 == strcmp(ps->data[i].Name, name))

 {

  break;

 }

}

if (i == ps->size)

{

 printf("要查找的人不存在\n");

}

else

{

 printf("找到了,联系人信息如下\n");

 printf("%-20s\t%-4s\t%-4s\t%-13s\t%-20s\n", "姓名", "年龄", "性别", "电话", "地址");

 printf("%-20s\t%-4d\t%-4s\t%-13s\t%-20s\n",

  ps->data[i].Name,

  ps->data[i].Age,

  ps->data[i].Sex,

  ps->data[i].Tel,

  ps->data[i].Address);

}

}


void SortContact(Contact* ps)

{

if (ps->size == 0)

{

 printf("通讯录为空,不能进行排序\n");

}

else

{

 int i = 0;

 int j = 0;

 PeoInfor temp;//按姓名进行从小到大排序

 for (i = 0; i < ps->size; i++)

 {

  for (j = 0; j < ps->size - i - 1; j++)

  {

   if (strcmp(ps->data[j].Name, ps->data[j + 1].Name) > 0)

   {

    temp = ps->data[j];

    ps->data[j] = ps->data[j + 1];

    ps->data[j + 1] = temp;

   }

  }

 }

 printf("排序成功\n");

}

}


void DestroyContact(Contact* ps)

{

free(ps->data);

ps->data = NULL;

}