一、通讯录的设计
该通讯录可以保存联系人的信息(名字、年龄、性别和地址)。我们可以通过指令对通讯录进行添加、删除、查找、修改、排序功能。可以将通讯录的实现的代码分在三个文件中,test.c用于通讯录的测试,contact.h用于声明结构体和功能函数,contact.c用于功能函数的实现。
二、通讯录的实现
2.1 通讯录的结构定义
2.1.1 联系人信息的结构体定义
联系人的信息包括姓名、年龄、性别、电话号码、地址。
typedef struct PeoInfo
{
char name[MAX_name];
int age;
char sex[MAX_sex];
char tele[MAX_tele];
char addr[MAX_addr];
}PeoInfo;
2.1.2 通讯录的结构体定义
通讯录包括联系人信息和通讯录长度。
typedef struct Contact
{
PeoInfo data[MAX];
int sz;
}Contact;
2.2 通讯录功能实现
2.2.1 显示功能菜单
将通讯录的各种功能打印在屏幕上。
void menu()
{
printf("***********************************\n");
printf("**** 1.添加 2.删除 *********\n");
printf("**** 3.查找 4.修改 *********\n");
printf("**** 5.显示 6.排序 *********\n");
printf("**** 0.退出 *********\n");
printf("***********************************\n");
}
2.2.2 初始化通讯录
将通讯录的信息内容赋值为初始值,再将长度设为0。
void InitContact(Contact* p)
{
assert(p);
for (int i = 0; i < MAX; i++)
{
strcpy(p->data[i].name, "0");
p->data[i].age=0;
strcpy(p->data[i].sex, "0");
strcpy(p->data[i].addr, "0");
strcpy(p->data[i].tele, "0");
}
p->sz= 0;
}
2.2.3 添加联系人信息
先判断通讯录是否已满,再输入联系人的信息,最后将通讯录长度加一。
void AddContach(Contact* p)
{
assert(p);
if (p->sz == MAX)
{
printf("通讯录已满,无法添加!\n");
return;
}
printf("请输入姓名:");
scanf("%s", p->data[p->sz].name);
printf("请输入年龄:");
scanf("%d", &(p->data[p->sz].age));
printf("请输入性别:");
scanf("%s", p->data[p->sz].sex);
printf("请输入电话:");
scanf("%s", p->data[p->sz].tele);
printf("请输入地址:");
scanf("%s", p->data[p->sz].addr);
p->sz++;
printf("成功添加联系人\n");
}
2.2.4 显示联系人信息
用for循环显示出联系人的信息。
void ShowContach(Contact* p)
{
assert(p);
printf("%-10s\t%-4s\t%-5s\t%-12s\t%-30s\n", "名字", "年龄", "性别", "电话", "地址");
for (int i = 0; i < p->sz; i++)
{
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].tele,
p->data[i].addr);
}
}
2.2.5 删除联系人信息
先判断通讯录是否为空,在输入要删除的联系人,可以设计一个函数用于找到联系人并返回联系人的位置,最后在通讯录中删除这个联系人,将后置的联系人先前补齐。
static int Findname(const Contact* p, char name[])
{
int i = 0;
for (i = 0; i < p->sz; i++)
{
if (strcmp(p->data[i].name, name) == 0)
{
return i; //找到
}
}
return -1; //没找到
}
void DelContach(Contact* p)
{
assert(p);
if (p->sz == 0)
{
printf("通讯录为空,无法删除\n");
return;
}
char name[MAX_name] = {0};
printf("请输入删除人的名字:");
scanf("%s", name);
int del = Findname(p, name);
if(del == -1)
{
printf("没有此人\n");
return;
}
int i = 0;
for (i = del; i < p->sz - 1; i++)
{
p->data[i] = p->data[i + 1];
}
printf("成功删除\n");
p->sz--;
}
2.2.6 查找联系人
我们用过查找联系人的函数找到该联系人,并输出联系人的信息。
void SearchContach(const Contact* p)
{
assert(p);
char name[MAX_name];
printf("请输入查找人的名字:");
scanf("%s", name);
int sear = Findname(p, name);
if (sear == -1)
printf("没有此人");
else
printf("%-10s\t%-4d\t%-5s\t%-12s\t%-30s\n",
p->data[sear].name,
p->data[sear].age,
p->data[sear].sex,
p->data[sear].tele,
p->data[sear].addr);
}
2.2.7 修改联系人信息
找到要修改的联系人的位置,并输入新的联系人信息代替原有的信息。
void ModifyContach(Contact* p)
{
assert(p);
char name[MAX_name];
printf("请输入修改人的名字:");
scanf("%s", name);
int modi = Findname(p, name);
if (modi == -1)
printf("没有此人");
else
{
printf("请输入姓名:");
scanf("%s", p->data[modi].name);
printf("请输入年龄:");
scanf("%d", &(p->data[modi].age));
printf("请输入性别:");
scanf("%s", p->data[modi].sex);
printf("请输入电话:");
scanf("%s", p->data[modi].tele);
printf("请输入地址:");
scanf("%s", p->data[modi].addr);
printf("修改成功\n");
}
}
2.2.8 按姓名排序联系人信息
先判断是否表空,可以用strcmp()函数作为判断的条件,若前面的字符串大于后面的字符串则会返回大于0的数,就可以接着用冒泡排序进行排序了。
void SortContach(Contact* p)
{
assert(p);
if (p->sz == 0)
{
printf("表空,无法排序\n");
return;
}
PeoInfo temp;
int i = 0;
int j = 0;
for (i = 0; i < p->sz; i++)
{
for(j = 0; j < p->sz - i - 1; j++)
{
if (strcmp(p->data[j].name, p->data[j + 1].name) > 0)
{
temp = p->data[j];
p->data[j] = p->data[j + 1];
p->data[j + 1] = temp;
}
}
}
printf("排序成功\n");
}
至此我们就实现了通讯录的所有功能。接下来就是将这些功能进行封装。
三、代码一览
3.1 test.c
#define _CRT_SECURE_NO_WARNINGS 1
#include "contact.h"
void menu()
{
printf("***********************************\n");
printf("**** 1.添加 2.删除 *********\n");
printf("**** 3.查找 4.修改 *********\n");
printf("**** 5.显示 6.排序 *********\n");
printf("**** 0.退出 *********\n");
printf("***********************************\n");
}
void test()
{
int input = 0;
Contact con;
InitContact(&con);
do
{
menu();
printf("请选择操作:");
scanf("%d", &input);
switch (input)
{
case 1:
AddContach(&con);
break;
case 2:
DelContach(&con);
break;
case 3:
SearchContach(&con);
break;
case 4:
ModifyContach(&con);
break;
case 5:
ShowContach(&con);
break;
case 6:
SortContach(&con);
break;
case 0:
printf("已退出!\n");
break;
default:
printf("输入错误请重新输入!\n");
break;
}
} while (input);
}
int main()
{
test();
return 0;
}
3.2 contact.h
#pragma once
#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
#include <assert.h>
#include <string.h>
#define MAX 100 //通讯录大小
#define MAX_name 30
#define MAX_sex 5
#define MAX_tele 12
#define MAX_addr 40
//声明结构体类型
typedef struct PeoInfo
{
char name[MAX_name];
int age;
char sex[MAX_sex];
char tele[MAX_tele];
char addr[MAX_addr];
}PeoInfo;
//通讯录
typedef struct Contact
{
PeoInfo data[MAX];
int sz;
}Contact;
//函数声明
//初始化通讯录
void InitContact(Contact *p);
//添加联系人信息
void AddContach(Contact* p);
//显示联系人信息
void ShowContach(Contact* p);
//删除联系人信息
void DelContach(Contact* p);
//查找联系人
void SearchContach(const Contact* p);
//修改联系人信息
void ModifyContach(Contact* p);
//按姓名排序联系人
void SortContach(Contact* p);
3.3 contact.c
#include "contact.h"
void InitContact(Contact* p)
{
assert(p);
for (int i = 0; i < MAX; i++)
{
strcpy(p->data[i].name, "0");
p->data[i].age=0;
strcpy(p->data[i].sex, "0");
strcpy(p->data[i].addr, "0");
strcpy(p->data[i].tele, "0");
}
p->sz= 0;
}
void AddContach(Contact* p)
{
assert(p);
if (p->sz == MAX)
{
printf("通讯录已满,无法添加!\n");
return;
}
printf("请输入姓名:");
scanf("%s", p->data[p->sz].name);
printf("请输入年龄:");
scanf("%d", &(p->data[p->sz].age));
printf("请输入性别:");
scanf("%s", p->data[p->sz].sex);
printf("请输入电话:");
scanf("%s", p->data[p->sz].tele);
printf("请输入地址:");
scanf("%s", p->data[p->sz].addr);
p->sz++;
printf("成功添加联系人\n");
}
void ShowContach(Contact* p)
{
assert(p);
printf("%-10s\t%-4s\t%-5s\t%-12s\t%-30s\n", "名字", "年龄", "性别", "电话", "地址");
for (int i = 0; i < p->sz; i++)
{
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].tele,
p->data[i].addr);
}
}
static int Findname(const Contact* p, char name[])
{
int i = 0;
for (i = 0; i < p->sz; i++)
{
if (strcmp(p->data[i].name, name) == 0)
{
return i; //找到
}
}
return -1; //没找到
}
void DelContach(Contact* p)
{
assert(p);
if (p->sz == 0)
{
printf("通讯录为空,无法删除\n");
return;
}
char name[MAX_name] = {0};
printf("请输入删除人的名字:");
scanf("%s", name);
/*int i = 0;
int del = 0;
int flag = 0;
for (i = 0; i < p->sz;i++)
{
if (strcmp(p->data[i].name, name)==0)
{
del = i;
flag = 1;
break;
}
}
if (flag == 0)
{
printf("没有此人\n");
return;
}*/
int del = Findname(p, name);
if(del == -1)
{
printf("没有此人\n");
return;
}
int i = 0;
for (i = del; i < p->sz - 1; i++)
{
p->data[i] = p->data[i + 1];
}
printf("成功删除\n");
p->sz--;
}
void SearchContach(const Contact* p)
{
assert(p);
char name[MAX_name];
printf("请输入查找人的名字:");
scanf("%s", name);
int sear = Findname(p, name);
if (sear == -1)
printf("没有此人");
else
printf("%-10s\t%-4d\t%-5s\t%-12s\t%-30s\n",
p->data[sear].name,
p->data[sear].age,
p->data[sear].sex,
p->data[sear].tele,
p->data[sear].addr);
}
void ModifyContach(Contact* p)
{
assert(p);
char name[MAX_name];
printf("请输入修改人的名字:");
scanf("%s", name);
int modi = Findname(p, name);
if (modi == -1)
printf("没有此人");
else
{
printf("请输入姓名:");
scanf("%s", p->data[modi].name);
printf("请输入年龄:");
scanf("%d", &(p->data[modi].age));
printf("请输入性别:");
scanf("%s", p->data[modi].sex);
printf("请输入电话:");
scanf("%s", p->data[modi].tele);
printf("请输入地址:");
scanf("%s", p->data[modi].addr);
printf("修改成功\n");
}
}
void SortContach(Contact* p)
{
assert(p);
if (p->sz == 0)
{
printf("表空,无法排序");
return;
}
PeoInfo temp;
int i = 0;
int j = 0;
for (i = 0; i < p->sz; i++)
{
for(j = 0; j < p->sz - i - 1; j++)
{
if (strcmp(p->data[j].name, p->data[j + 1].name) > 0)
{
temp = p->data[j];
p->data[j] = p->data[j + 1];
p->data[j + 1] = temp;
}
}
}
printf("排序成功");
}