学结构体学了这么久,终于要用结构体做点东西了。接下来就用结构体的知识实现一个简陋的通讯录。
和之前一样采用模块化的方式创建三个文件即可,一个测试文件text.c,一个contact.c为通讯录的具体实现以及contact.h用来存放实现contact.c的函数声明和类型。
#pragma once
#include
#include
#include
#define MAX 1000
#define MAX_NAME 20
#define MAX_SEX 5
#define MAX_ADDER 30
#define MAX_TELE 15
//类型声明
enum Option
{
EXIT,//0
ADD,//1
DELETE,//2
SEARCH,//3
MODIFY,//4
SHOW,//5
SORT//6
};
typedef struct PerInfo {
int age;
char name[MAX_NAME];
char sex[MAX_SEX];
char adder [MAX_ADDER];
char tele[MAX_TELE];
}PerInfo;
typedef struct contact
{
PerInfo data[MAX];
int len;
}contact;
//函数声明
//初始化通讯录
void InitContact(contact* ps);
void AddContact(contact* ps);
void ShowContact(contact* ps);
void DeleteContact(contact *ps);
void SearchContact(contact *ps);
void ModifyContact(contact *ps);
void SortContact(contact* ps)
首先通讯录本身可以看做是一个存放数据的容器,而里面的信息就是联系人的具体信息,既然我们要描述一个人的信息,如姓名,年龄,地址等,是用单一的内置类型是无法具体描述的,我们采用结构体这种复杂类型去描述人这个对象,第一步我们将创建一个用来描述人的结构体。
typedef struct PerInfo {
int age;
char name[MAX_NAME];
char sex[MAX_SEX];
char adder [MAX_ADDER];
char tele[MAX_TELE];
}PerInfo;
通讯录里面是不可能存放一个人的信息,它是要具备最基本的增删改查,本身也要具备一定的大小才能去存储信息。所以我们创建一个容量为1000PerInfo的数组的,当我们向里面加入一个人的信息时,我们需要知道通讯录的 容量是否已经达到最值,一旦达到便无法加入信息,由此可知,我们需要一个变量去统计通讯录中的人数。此时我们如果进行增删改查,我们传参的时候即要传联系人的信息和人数,为了减少传参的个数,我们可以将联系人和人数一起放到一个结构体中。该结构体就定义为通讯录。
typedef struct contact
{
PerInfo data[MAX];
int len;
}contact;
当我们创建好通讯录后需要对通讯录中的数组和变量进行初始化,如果不初始化的话,里面的值都是系统生成的随机值,是无意义的。所以我们将通讯录中的数据都初始化为0,并将这个功能单独定义成一个函数。
void InitContact(contact* ps)
{
ps->len = 0;
memset(ps->data,0,sizeof(ps->data));
}
此时一个空白的数据就创建好了。
首先我们要判断通讯录中是否已满,如果已满自然不能加入联系人。如果未满,则添加联系人。我们初始化的时候数组和人数都是0,我们不妨将人数len当做数组的下标来操作,当联系人的信息成功添加len则++。
void AddContact(contact* ps)
{
if (ps->len == MAX)
{
printf("通讯录已满,无法添加");
return;
}
printf("请输入您要xxx的基本信息:\n");
printf("请输入姓名:");
scanf("%s", ps->data[ps->len].name);
printf("请输入年龄:");
scanf("%d", &(ps->data[ps->len].age));
printf("请输入性别:");
scanf("%s", ps->data[ps->len].sex);
printf("请输入手机号码:");
scanf("%s", ps->data[ps->len].tele);
printf("请输入住址:");
scanf("%s", ps->data[ps->len].adder);
ps->len++;
printf("添加成功!\n");
}
我们先要先判断通讯录是否为空,为空无法删,否则就删。我们删除的前提是要找到某个联系人,就像我们在微信上拉黑某人的去列表中找他在删他。所以我们现在通讯录不为空的前提下查找某一联系人的姓名,当我们找到的时候就删了它。又因为这个查找联系人的功能我们在后面的功能里面也会使用,所以也将它封装成一个函数,以便后面使用。
int isByName(contact *ps,char name[])
{
for (int i = 0; i < ps->len; i++)
{
if (0 == strcmp(ps->data[i].name, name))
{
return 1;
}
}
return -1;
}
void DeleteContact(contact *ps)
{
assert(ps);
char name[20] = { 0 };
printf("请输入您要删除的联系人的名字:");
scanf("%s", name);
int ret=isByName(ps, name);
if (ps->len >= 0)
{
printf("通讯录为空,无法删除\n");
return;
}
if (ret == -1)
{
printf("查无此人");
}
else
{
for (int i = 0; i < ps->len - 1; i++)
{
ps->data[i] = ps->data[i + 1];
}
ps->len--;
printf("删除成功!\n");
}
}
修改联系人和删除联系人的逻辑基本一致,也是先找后操作。我们采用的是传址调用。所以我们找到人之后再重新说输入一遍新联系人的信息便能更改。
void ModifyContact(contact* ps)
{
assert(ps);
char name[20] = { 0 };
printf("请输入您要修改的联系人的名字:");
scanf("%s", name);
int pos = isByName(ps, name);
if (pos == -1)
{
printf("查无此人");
}
else
{
printf("请输入姓名:");
scanf("%s", ps->data[pos].name);
printf("请输入年龄:");
scanf("%d", &(ps->data[pos].age));
printf("请输入性别:");
scanf("%s", ps->data[pos].sex);
printf("请输入手机号码:");
scanf("%s", ps->data[pos].tele);
printf("请输入住址:");
scanf("%s", ps->data[pos].adder);
printf("添加修改!\n");
}
}
查找就是在通讯录中去找,找到了将打印该联系人的信息,没有找到则打印查无此人。
void SearchContact(contact* ps)
{
assert(ps);
char name[20] = { 0 };
printf("请输入您要查找的联系人的名字:");
scanf("%s", name);
int pos = isByName(ps, name);
if (pos == -1)
{
printf("查无此人");
}
else
{
printf("%-20s %-5s %-5s %-12s %-30s\n", "姓名", "年龄", "性别", "手机号码", "地址");
printf("%-20s %-5d %-5s %-12s %-30s\n", ps->data[pos].name, ps->data[pos].age
, ps->data[pos].sex, ps->data[pos].tele, ps->data[ps].adder);
}
}
我们这里采用的是根据姓名进行排序,也可以按照年龄只需要更改比较规则即可。
int ComparyByName(const void* e1, const void* e2)
{
return strcmp((const char*)e1, (const char*)e2);
}
void SortContact(contact* ps)
{
qsort(ps->data, ps->len, sizeof(PerInfo), ComparyByName);
}
只需要将通讯录中信息打印出来即可。
void ShowContact(contact* ps)
{
assert(ps);
printf("%-20s %-5s %-5s %-12s %-30s\n", "姓名", "年龄", "性别", "手机号码", "地址");
for (int i = 0; i < ps->len; i++)
{
printf("%-20s %-5d %-5s %-12s %-30s\n", ps->data[i].name, ps->data[i].age
, ps->data[i].sex, ps->data[i].tele, ps->data[i].adder);
}
}
通讯录基本的功能实现了,为了界面友好与操作,就为通讯录整个菜单。
void menu()
{
printf("**|******************|**\n");
printf("**|1.Add 2.Delete***|**\n");
printf("**|3.Seacher 4.Modify|**\n");
printf("** |5.Show 6.Sort| **\n");
printf("** |0.Exit| **\n");
printf("**********|***|*********\n");
printf("************|***********\n");
}
我们将菜单具体实现也就是操作通讯录的过程也封装成一个函数。
void text()
{
int input = 0;
contact con;
InitContact(&con);
do {
menu();
printf("请输入您的选择:");
scanf("%d", &input);
switch (input)
{
case ADD:
AddContact(&con);
break;
case DELETE:
DeleteContact(&con);
break;
case SEARCH:
SearchContact(&con);
break;
case MODIFY:
ModifyContact(&con);
break;
case SHOW:
ShowContact(&con);
break;
case SORT:
SortContact(&con);
break;
case EXIT:
printf("退出通讯录");
break;
default:
printf("您的选择有误,请重新输入!");
}
} while (input);
}
//contact.h文件用于声明函数和类型
#pragma once
#include
#include
#include
#define MAX 1000
#define MAX_NAME 20
#define MAX_SEX 5
#define MAX_ADDER 30
#define MAX_TELE 15
//类型声明
enum Option
{
EXIT,//0
ADD,//1
DELETE,//2
SEARCH,//3
MODIFY,//4
SHOW,//5
SORT//6
};
typedef struct PerInfo {
int age;
char name[MAX_NAME];
char sex[MAX_SEX];
char adder [MAX_ADDER];
char tele[MAX_TELE];
}PerInfo;
typedef struct contact
{
PerInfo data[MAX];
int len;
}contact;
//函数声明
//初始化通讯录
void InitContact(contact* ps);
void AddContact(contact* ps);
void ShowContact(contact* ps);
void DeleteContact(contact *ps);
void SearchContact(contact *ps);
void ModifyContact(contact *ps);
void SortContact(contact* ps);
//contact.c文件 通讯录功能的具体实现
#define _CRT_SECURE_NO_WARNINGS 1
#include "contact.h"
void InitContact(contact* ps)
{
ps->len = 0;
memset(ps->data,0,sizeof(ps->data));
}
void AddContact(contact* ps)
{
if (ps->len == MAX)
{
printf("通讯录已满,无法添加");
return;
}
printf("请输入您要xxx的基本信息:\n");
printf("请输入姓名:");
scanf("%s", ps->data[ps->len].name);
printf("请输入年龄:");
scanf("%d", &(ps->data[ps->len].age));
printf("请输入性别:");
scanf("%s", ps->data[ps->len].sex);
printf("请输入手机号码:");
scanf("%s", ps->data[ps->len].tele);
printf("请输入住址:");
scanf("%s", ps->data[ps->len].adder);
ps->len++;
printf("添加成功!\n");
}
void ShowContact(contact* ps)
{
assert(ps);
printf("%-20s %-5s %-5s %-12s %-30s\n", "姓名", "年龄", "性别", "手机号码", "地址");
for (int i = 0; i < ps->len; i++)
{
printf("%-20s %-5d %-5s %-12s %-30s\n", ps->data[i].name, ps->data[i].age
, ps->data[i].sex, ps->data[i].tele, ps->data[i].adder);
}
}
int isByName(contact *ps,char name[])
{
for (int i = 0; i < ps->len; i++)
{
if (0 == strcmp(ps->data[i].name, name))
{
return 1;
}
}
return -1;
}
void DeleteContact(contact *ps)
{
assert(ps);
char name[20] = { 0 };
printf("请输入您要删除的联系人的名字:");
scanf("%s", name);
int ret=isByName(ps, name);
if (ps->len >= 0)
{
printf("通讯录为空,无法删除\n");
return;
}
if (ret == -1)
{
printf("查无此人");
}
else
{
for (int i = 0; i < ps->len - 1; i++)
{
ps->data[i] = ps->data[i + 1];
}
ps->len--;
printf("删除成功!\n");
}
}
void SearchContact(contact* ps)
{
assert(ps);
char name[20] = { 0 };
printf("请输入您要查找的联系人的名字:");
scanf("%s", name);
int pos = isByName(ps, name);
if (pos == -1)
{
printf("查无此人");
}
else
{
printf("%-20s %-5s %-5s %-12s %-30s\n", "姓名", "年龄", "性别", "手机号码", "地址");
printf("%-20s %-5d %-5s %-12s %-30s\n", ps->data[pos].name, ps->data[pos].age
, ps->data[pos].sex, ps->data[pos].tele, ps->data[pos].adder);
}
}
void ModifyContact(contact* ps)
{
assert(ps);
char name[20] = { 0 };
printf("请输入您要修改的联系人的名字:");
scanf("%s", name);
int pos = isByName(ps, name);
if (pos == -1)
{
printf("查无此人");
}
else
{
printf("请输入姓名:");
scanf("%s", ps->data[pos].name);
printf("请输入年龄:");
scanf("%d", &(ps->data[pos].age));
printf("请输入性别:");
scanf("%s", ps->data[pos].sex);
printf("请输入手机号码:");
scanf("%s", ps->data[pos].tele);
printf("请输入住址:");
scanf("%s", ps->data[pos].adder);
printf("添加修改!\n");
}
}
int ComparyByName(const void* e1, const void* e2)
{
return strcmp((const char*)e1, (const char*)e2);
}
void SortContact(contact* ps)
{
qsort(ps->data, ps->len, sizeof(PerInfo), ComparyByName);
}
//text.c文件 通讯录的启动
#define _CRT_SECURE_NO_WARNINGS 1
#include
#include "contact.h"
void menu()
{
printf("**|******************|**\n");
printf("**|1.Add 2.Delete***|**\n");
printf("**|3.Seacher 4.Modify|**\n");
printf("** |5.Show 6.Sort| **\n");
printf("** |0.Exit| **\n");
printf("**********|***|*********\n");
printf("************|***********\n");
}
void text()
{
int input = 0;
contact con;
InitContact(&con);
do {
menu();
printf("请输入您的选择:");
scanf("%d", &input);
switch (input)
{
case ADD:
AddContact(&con);
break;
case DELETE:
DeleteContact(&con);
break;
case SEARCH:
SearchContact(&con);
break;
case MODIFY:
ModifyContact(&con);
break;
case SHOW:
ShowContact(&con);
break;
case SORT:
SortContact(&con);
break;
case EXIT:
printf("退出通讯录");
break;
default:
printf("您的选择有误,请重新输入!");
}
} while (input);
}
int main()
{
text();
return 0;
}