建立3个文件,test.c,contact.c和contact.h
其中,test.c用于存放主体框架;
contact.h用于存放各功能函数的声明,需要用到的头文件,以及一些重命名变量;
contact.c用于存放实现各功能的模块。
在整体框架搭建好的基础上,我们来填充各模块。
模块框架如下:
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");
}
int main()
{
int input = 0;
//创建通讯录
Contact con;
//初始化通讯录
InitContact(&con);//传递整个结构体
do
{
menu();
printf("请选择:>\n");
scanf("%d",&input);
switch (input)
{
case 1:
AddContact(&con);
break;
case 2:
DelContact(&con);
break;
case 3:
SearchContact(&con);
break;
case 4:
ModifyContact(&con);
break;
case 5:
ShowContact(&con);
break;
case 6:
QortContact(&con);
break;
case 0:
printf("退出通讯录\n");
break;
default:
printf("选择错误,请重新选择\n");
break;
}
} while (input);
return 0;
}
框架做完后,类型的定义 人的信息,包括姓名,年龄,性 别,地址,电话;
定义中出现的数字可以重定义为标识符常量;
做成结构体的形式,觉得类型名复杂,可以重定义;
创建通讯录,数组,100个;
test.c需要包含contact.h文件;
sz记录通讯录当前存放的信息的个数;
再创建一个结构体,将sz和通讯录的信息记录起来;
可以用typedef进行重命名;
重新创建通讯录con;
初始化通讯录
assert 断言;
简单粗暴的处理:直接赋值为0,即:Contact con={0};
或者封装一个函数:InitContact,参数传递为指针;
contact.c文件需要包含contact.h文件;
对于sz可以直接赋值为0,对于数组这多大的一块空间,可以使用memset进行初始化;
void * memset ( void * ptr, int value, size_t num );
sizeof(pc->data) pc 这里传递的是整个结构体 计算的是整个数组的大小;
#define NAME_MAX 20
#define SEX_MAX 5
#define ADDRESS_MAX 30
#define TELEPHONE_MAX 12
#define MAX 100
//人的信息
typedef struct peopleinformaition
{
char name[NAME_MAX];
int age;
char sex[SEX_MAX];
char address[ADDRESS_MAX];
char telephone[TELEPHONE_MAX];
}PeoInfo;
//通讯录
typedef struct Contact
{
PeoInfo data[MAX];//可以存放max个人的信息
int sz;//sz 表示当前已存放的人的个数
}Contact;
/初始化通讯录
void InitContact(Contact* pc)
{
assert(pc);
memset(pc->data,0,sizeof(pc->data));
pc->sz = 0;
}
增加加通讯录;
assert 断言;
放置到下标为sz的位置上;
先判断通讯录是否已满MAX,若已满,renturn返回,什么都不携带;
增加一个人的信息:printf和scanf;
pc->data[pc->sz]是一个结构体,name是一个数组;
//增加通讯录
void AddContact(Contact* pc)
{
assert(pc);
if (pc->sz==MAX)
{
printf("通讯录已满\n");
}
printf("请输入人的姓名\n");
scanf("%s",pc->data[pc->sz].name);
printf("请输入人的年龄\n");
scanf("%d", &(pc->data[pc->sz].age));
printf("请输入人的性别\n");
scanf("%s", pc->data[pc->sz].sex);
printf("请输入人的地址\n");
scanf("%s", pc->data[pc->sz].address);
printf("请输入人的电话\n");
scanf("%s", pc->data[pc->sz].telephone);
pc->sz++;
}
显示通讯录;
assert 断言;
for循环打印,一个printf;
\t 水平制表符,相当于tab;
%20s 控制宽度;
%-20s 左对齐,默认为右对齐;
一个汉字在存储的时候需要占2个字节的空间;
优化:可以先打印出表头 表头中的年龄是字符串,需要改动%d为%s;
打印部分加上const ;
//显示通讯录
void ShowContact(const Contact* pc)
{
assert(pc);
int i = 0;
printf("%-15s\t%-2s\t%-s\t%-25s\t%-12s\n", "姓名", "年龄", "性别", "地址", "电话");
for (i=0;i<pc->sz;i++)
{
printf("%-15s\t%-2d\t%-s\t%-25s\t%-12s\n",pc->data[i].name,
pc->data[i].age,
pc->data[i].sex,
pc->data[i].address,
pc->data[i].telephone);
}
}
删除通讯录;
没有元素就不能删除了;
找到要删除的人;
输入要删除人的名字,用strcmp对比;
找到之后,用del记住它的下标;
删除的方式:后面的元素向前覆盖或者最后一个元素移动到这里覆盖掉这个元素;
选择后面的元素向前覆盖;
i+1的元素赋给i,sz的最大值为‘sz-1’;
sz–;
给出反馈;
封装查找的动作,为函数findbyname( 参1,参2),找到给出下标,没找到返回-1;
int FindByName(const Contact* pc, char name[NAME_MAX])
{
int i = 0;
for (i = 0; i < pc->sz; i++)
{
if (strcmp(pc->data[i].name, name) == 0)
{
return i;
}
}
return -1;
}
//删除通讯录
void DelContact(Contact* pc)
{
assert(pc);
char name[NAME_MAX];
if (pc->sz==0)
{
printf("通讯录为空,不能删除\n");
return;
}
//查找这个人
printf("请输入要删除人的名字\n");
scanf("%s",name);
int ret = FindByName(pc, name);
if (-1==ret)
{
printf("没有找到这个人\n");
return;
}
//删除
int i = 0;
for (i=ret;i<pc->sz-1;i++)
{
pc->data[i] = pc->data[i + 1];
}
pc->sz--;
printf("删除成功\n");
}
7.查找通讯录;
可以加const;
输入要查找人的名字;
调用FindByName函数;
判断人的信息是否存在;
若存在,用pos标记,打印信息;
模块代码如下:
//查找通讯录
void SearchContact(const Contact* pc)
{
assert(pc);
char name[NAME_MAX];
printf("请输入要查找人的名字\n");
scanf("%s",name);
int pos = FindByName(pc,name);
if (-1==pos)
{
printf("要查找人的信息不存在");
return;
}
printf("%-15s\t%-2s\t%-s\t%-25s\t%-12s\n", "姓名", "年龄", "性别", "地址", "电话");
printf("%-15s\t%-2d\t%-s\t%-25s\t%-12s\n", pc->data[pos].name,
pc->data[pos].age,
pc->data[pos].sex,
pc->data[pos].address,
pc->data[pos].telephone);
}
8.修改通讯录;
先查找这个人的信息,再去修改;
输入要查找人的名字;
调用FindByName函数;
判断人的信息是否存在;
修改信息就是重新再录一遍;
增加一个人的信息:printf和scanf;
pc->data[pc->sz]是一个结构体,name是一个数组;
提示信息,修改完成;
//修改通讯录
void ModifyContact(Contact* pc)
{
assert(pc);
char name[NAME_MAX];
printf("请输入要修改人的名字\n");
scanf("%s", name);
int pos = FindByName(pc, name);
if (-1 == pos)
{
printf("要修改人的信息不存在");
return;
}
printf("请输入人的姓名\n");
scanf("%s", pc->data[pos].name);
printf("请输入人的年龄\n");
scanf("%d", &(pc->data[pos].age));
printf("请输入人的性别\n");
scanf("%s", pc->data[pos].sex);
printf("请输入人的地址\n");
scanf("%s", pc->data[pos].address);
printf("请输入人的电话\n");
scanf("%s", pc->data[pos].telephone);
}
排序通讯录
按年龄进行排序;
排序,传递给qsort的不能是单个元素,传递数组;
排完序后打印出来;
模块代码如下:
int CompareByAge(const void* a, const void* b)
{
return ((PeoInfo*)a)->age- ((PeoInfo*)b)->age;
}
//排序通讯录
void QortContact(Contact* pc)
{
assert(pc);
qsort(pc->data, pc->sz, sizeof(pc->data[0]), CompareByAge);
printf("排序后的通讯录\n");
int i = 0;
printf("%-15s\t%-2s\t%-s\t%-25s\t%-12s\n", "姓名", "年龄", "性别", "地址", "电话");
for (i = 0; i < pc->sz; i++)
{
printf("%-15s\t%-2d\t%-s\t%-25s\t%-12s\n", pc->data[i].name,
pc->data[i].age,
pc->data[i].sex,
pc->data[i].address,
pc->data[i].telephone);
}
}
test.c
#include "contact.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");
}
int main()
{
int input = 0;
//创建通讯录
Contact con;
//初始化通讯录
InitContact(&con);//传递整个结构体
do
{
menu();
printf("请选择:>\n");
scanf("%d",&input);
switch (input)
{
case 1:
AddContact(&con);
break;
case 2:
DelContact(&con);
break;
case 3:
SearchContact(&con);
break;
case 4:
ModifyContact(&con);
break;
case 5:
ShowContact(&con);
break;
case 6:
QortContact(&con);
break;
case 0:
printf("退出通讯录\n");
break;
default:
printf("选择错误,请重新选择\n");
break;
}
} while (input);
return 0;
}
contact.h
#pragma once
#include
#include
#include
#include
#define NAME_MAX 20
#define SEX_MAX 5
#define ADDRESS_MAX 30
#define TELEPHONE_MAX 12
#define MAX 100
//人的信息
typedef struct peopleinformaition
{
char name[NAME_MAX];
int age;
char sex[SEX_MAX];
char address[ADDRESS_MAX];
char telephone[TELEPHONE_MAX];
}PeoInfo;
//通讯录
typedef struct Contact
{
PeoInfo data[MAX];//可以存放max个人的信息
int sz;//sz 表示当前已存放的人的个数
}Contact;
//初始化通讯录
void InitContact(Contact* pc);
//增加通讯录
void AddContact(Contact* pc);
//显示通讯录
void ShowContact(const Contact* pc);
//删除通讯录
void DelContact(Contact* pc);
//查找通讯录
void SearchContact(const Contact* pc);
//修改通讯录
void ModifyContact(Contact* pc);
//排序通讯录
void QortContact(Contact* pc);
contact.c
#include "contact.h"
//初始化通讯录
void InitContact(Contact* pc)
{
assert(pc);
memset(pc->data,0,sizeof(pc->data));
pc->sz = 0;
}
//增加通讯录
void AddContact(Contact* pc)
{
assert(pc);
if (pc->sz==MAX)
{
printf("通讯录已满\n");
}
printf("请输入人的姓名\n");
scanf("%s",pc->data[pc->sz].name);
printf("请输入人的年龄\n");
scanf("%d", &(pc->data[pc->sz].age));
printf("请输入人的性别\n");
scanf("%s", pc->data[pc->sz].sex);
printf("请输入人的地址\n");
scanf("%s", pc->data[pc->sz].address);
printf("请输入人的电话\n");
scanf("%s", pc->data[pc->sz].telephone);
pc->sz++;
}
//显示通讯录
void ShowContact(const Contact* pc)
{
assert(pc);
int i = 0;
printf("%-15s\t%-2s\t%-s\t%-25s\t%-12s\n", "姓名", "年龄", "性别", "地址", "电话");
for (i=0;i<pc->sz;i++)
{
printf("%-15s\t%-2d\t%-s\t%-25s\t%-12s\n",pc->data[i].name,
pc->data[i].age,
pc->data[i].sex,
pc->data[i].address,
pc->data[i].telephone);
}
}
int FindByName(const Contact* pc, char name[NAME_MAX])
{
int i = 0;
for (i = 0; i < pc->sz; i++)
{
if (strcmp(pc->data[i].name, name) == 0)
{
return i;
}
}
return -1;
}
//删除通讯录
void DelContact(Contact* pc)
{
assert(pc);
char name[NAME_MAX];
if (pc->sz==0)
{
printf("通讯录为空,不能删除\n");
return;
}
//查找这个人
printf("请输入要删除人的名字\n");
scanf("%s",name);
int ret = FindByName(pc, name);
if (-1==ret)
{
printf("没有找到这个人\n");
return;
}
//删除
int i = 0;
for (i=ret;i<pc->sz-1;i++)
{
pc->data[i] = pc->data[i + 1];
}
pc->sz--;
printf("删除成功\n");
}
//查找通讯录
void SearchContact(const Contact* pc)
{
assert(pc);
char name[NAME_MAX];
printf("请输入要查找人的名字\n");
scanf("%s",name);
int pos = FindByName(pc,name);
if (-1==pos)
{
printf("要查找人的信息不存在");
return;
}
printf("%-15s\t%-2s\t%-s\t%-25s\t%-12s\n", "姓名", "年龄", "性别", "地址", "电话");
printf("%-15s\t%-2d\t%-s\t%-25s\t%-12s\n", pc->data[pos].name,
pc->data[pos].age,
pc->data[pos].sex,
pc->data[pos].address,
pc->data[pos].telephone);
}
//修改通讯录
void ModifyContact(Contact* pc)
{
assert(pc);
char name[NAME_MAX];
printf("请输入要修改人的名字\n");
scanf("%s", name);
int pos = FindByName(pc, name);
if (-1 == pos)
{
printf("要修改人的信息不存在");
return;
}
printf("请输入人的姓名\n");
scanf("%s", pc->data[pos].name);
printf("请输入人的年龄\n");
scanf("%d", &(pc->data[pos].age));
printf("请输入人的性别\n");
scanf("%s", pc->data[pos].sex);
printf("请输入人的地址\n");
scanf("%s", pc->data[pos].address);
printf("请输入人的电话\n");
scanf("%s", pc->data[pos].telephone);
}
int CompareByAge(const void* a, const void* b)
{
return ((PeoInfo*)a)->age- ((PeoInfo*)b)->age;
}
//排序通讯录
void QortContact(Contact* pc)
{
assert(pc);
qsort(pc->data, pc->sz, sizeof(pc->data[0]), CompareByAge);
printf("排序后的通讯录\n");
int i = 0;
printf("%-15s\t%-2s\t%-s\t%-25s\t%-12s\n", "姓名", "年龄", "性别", "地址", "电话");
for (i = 0; i < pc->sz; i++)
{
printf("%-15s\t%-2d\t%-s\t%-25s\t%-12s\n", pc->data[i].name,
pc->data[i].age,
pc->data[i].sex,
pc->data[i].address,
pc->data[i].telephone);
}
}