目录
通讯录可以用来存储1000个人的信息,每个人的信息包括:姓名、性别、年龄、电话、住址
功能:
- 添加联系人信息
- 删除指定联系人信息
- 查找指定联系人信息
- 修改指定联系人信息
- 显示所有联系人信息
- 清空所有联系人
- 以名字排序所有联系人
固定大小通讯录 <-这是静态大小的通讯录
这个动态大小的通讯录可以先开辟较小的空间,后根据需求再开辟所需要的空间,更节约内存空间
写这个通讯录需要对结构体成员访问、动态内存分配的知识有一定的了解
定义通讯录结构体
#define NAME_MAX 20
#define SEX_MAX 5
#define AGE_MAX 3
#define TELE_MAX 12
#define ADDR_MAX 20
#define BASIC 5
//单个联系人信息
typedef struct PeoInfo
{
char name[NAME_MAX];
char sex[SEX_MAX];
char age[AGE_MAX];
char tele[TELE_MAX];
char addr[ADDR_MAX];
}PeoInfo;
typedef struct Contact
{
PeoInfo* data;
int sz; //已存联系人数量
int capacity; //此通讯录最大可存联系人数量
}Contact;
通讯录初始化
先开辟自定义的BASIC个联系人空间
//通讯录初始化
void init_contact(Contact* pc)
{
assert(pc);
pc->capacity = BASIC;
pc->sz = 0;
pc->data = (PeoInfo*)malloc(pc->capacity * sizeof(PeoInfo));
if (pc->data == NULL)
{
perror("init_contact:malloc");
return;
}
memset(pc->data,0, pc->capacity * sizeof(PeoInfo));
}
检查空间大小
这里判断sz==capacity-1,而不是sz==capacity,是因为data数组的最后一项pc->data[pc->capacity]要为空,用作后面的排序时用的的临时数据。所以通讯录的实际可用大小为capacity-1
//检查通讯录大小是否已满,满则扩容
void check_capacity(Contact* pc)
{
assert(pc);
if (pc->sz == pc->capacity - 1)
{
PeoInfo* temp = realloc(pc->data, (pc->capacity + 2) * sizeof(PeoInfo));
if (temp == NULL)
{
perror("check_capacity:");
return;
}
else
{
pc->data = temp;
pc->capacity += 2;
}
}
}
新增联系人信息
这里和静态通讯录相似,只是在新增之前要检查通讯录大小是否足够大,要调用check_capacity函数
//新增联系人信息
void add_contact(Contact* pc)
{
assert(pc);
check_capacity(pc);
printf("请输入姓名:");
scanf("%s", pc->data[pc->sz].name);
printf("请输入性别:");
scanf("%s", pc->data[pc->sz].sex);
printf("请输入年龄:");
scanf("%s", pc->data[pc->sz].age);
printf("请输入电话:");
scanf("%s", pc->data[pc->sz].tele);
printf("请输入住址:");
scanf("%s", pc->data[pc->sz].addr);
pc->sz++; //联系人数目变化
}
通过姓名查找联系人
//查找是否有此联系人,有则返回下标
int find_name(Contact* pc, char* name)
{
assert(pc);
int ret = 0;
for (int i = 0; i < pc->sz; i++)
{
if (0 == strcmp(name, pc->data[i].name))
{
return i;
}
else if (i == pc->sz)
{
return -1;
}
}
return -1;
}
删除指定联系人信息
这里和静态通讯录相似
//删除指定联系人信息
void delete_contact(Contact* pc)
{
assert(pc);
char dname[NAME_MAX];
printf("请输入删除的联系人姓名:");
scanf("%s", dname);
if (find_name(pc, dname) != -1)
{
//用后一个联系人的信息替换掉前一个联系人的信息
for (int j = find_name(pc, dname); j < pc->sz - 1; j++)
{
pc->data[j] = pc->data[j + 1];
}
pc->sz--;
printf("删除成功\n\n");
}
else
{
printf("找不到该联系人\n\n");
}
}
打印所有联系人信息
这里和静态通讯录相似
//打印通讯录
void print_contact(Contact* pc)
{
assert(pc);
printf("%-20s %-5s %-5s %-15s %-20s\n", "姓名", "性别", "年龄", "电话号码", "住址");
for (int i = 0; i < pc->sz; i++)
{
printf("%-20s %-5s %-5s %-15s %-20s\n", pc->data[i].name, pc->data[i].sex, pc->data[i].age, pc->data[i].tele, pc->data[i].addr);
}
printf("\n");
}
查找指定联系人信息
这里和静态通讯录相似
//查找指定联系人信息
void search_contact(Contact* pc)
{
assert(pc);
char sname[NAME_MAX];
printf("请输入联系人姓名:");
scanf("%s", sname);
int ret = find_name(pc, sname);
if (ret != -1)
{
printf("%-20s %-5s %-5s %-15s %-20s\n", "姓名", "性别", "年龄", "电话号码", "住址");
printf("%-20s %-5s %-5s %-15s %-20s\n\n", pc->data[ret].name, pc->data[ret].sex, pc->data[ret].age, pc->data[ret].tele, pc->data[ret].addr);
}
else
{
printf("找不到此联系人\n\n");
}
}
删除指定联系人信息
这里和静态通讯录相似
//修改指定联系人信息
void modify_contact(Contact* pc)
{
assert(pc);
char mname[NAME_MAX];
printf("请输入需要修改的联系人:");
scanf("%s", mname);
int ret = find_name(pc, mname);
if (ret != -1)
{
printf("请输入新的联系人信息:\n");
printf("姓名:");
scanf("%s", pc->data[ret].name);
printf("性别:");
scanf("%s", pc->data[ret].sex);
printf("年龄:");
scanf("%s", pc->data[ret].age);
printf("电话:");
scanf("%s", pc->data[ret].tele);
printf("住址:");
scanf("%s", pc->data[ret].addr);
printf("修改成功\n\n");
}
else
{
printf("此联系人不存在\n\n");
}
}
清空所有联系人信息
//清空所有联系人
void clean_contact(Contact* pc)
{
assert(pc);
printf("请确认清空所有联系人:\n");
printf("1->YES 2->NO\n");
int judge = 0;
scanf("%d", &judge);
if (judge == 1)
{
free_contact(pc);
printf("已清空\n\n");
}
else
{
return;
}
}
通过名字排序联系人
冒泡排序
//按名字排序联系人
void sort_contact(Contact* pc)
{
assert(pc);
int upordown = 0;
printf("请选择排序方式:\n");
printf("1->升序 2->降序\n");
scanf("%d", &upordown);
if (upordown == 1)
{
for (int i = 0; i < pc->sz - 1; i++)
for (int j = 0; j < pc->sz - 1 - i; j++)
{
if (strcmp(pc->data[j].name, pc->data[j + 1].name) > 0)
{
pc->data[pc->capacity - 1] = pc->data[j];
pc->data[j] = pc->data[j + 1];
pc->data[j + 1] = pc->data[pc->capacity - 1];
}
}
printf("已按姓名升序排列\n\n");
}
else if (upordown == 2)
{
for (int i = 0; i < pc->sz - 1; i++)
for (int j = 0; j < pc->sz - 1 - i; j++)
{
if (strcmp(pc->data[j].name, pc->data[j + 1].name) < 0)
{
pc->data[pc->capacity - 1] = pc->data[j];
pc->data[j] = pc->data[j + 1];
pc->data[j + 1] = pc->data[pc->capacity - 1];
}
}
printf("已按姓名降序排列\n\n");
}
else
{
printf("输入错误\n");
return;
}
}
完整代码:
头文件
#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<assert.h>
#define NAME_MAX 20
#define SEX_MAX 5
#define AGE_MAX 3
#define TELE_MAX 12
#define ADDR_MAX 20
#define BASIC 5
enum
{
EXIT, //0
ADD,
DELE,
SEARCH,
MODIFY,
PRINT,
CLEAN,
SORT,
};
//单个联系人信息
typedef struct PeoInfo
{
char name[NAME_MAX];
char sex[SEX_MAX];
char age[AGE_MAX];
char tele[TELE_MAX];
char addr[ADDR_MAX];
}PeoInfo;
typedef struct Contact
{
PeoInfo* data;
int sz; //已存联系人数量
int capacity; //此通讯录最大可存联系人数量
}Contact;
//初始化
void init_contact(Contact* pc);
//新增联系人信息
void add_contact(Contact* pc);
//打印通讯录
void print_contact(Contact* pc);
//查找是否有此联系人,有则返回下标
int find_name(Contact* pc, char* name);
//删除指定联系人信息
void delete_contact(Contact* pc);
//查找指定联系人信息
void search_contact(Contact* pc);
//修改指定联系人信息
void modify_contact(Contact* pc);
//清空所有联系人
void clean_contact(Contact* pc);
//按名字排序联系人
void sort_contact(Contact* pc);
功能函数
#define _CRT_SECURE_NO_WARNINGS 1
#include"contact2.0.h"
//通讯录初始化
void init_contact(Contact* pc)
{
assert(pc);
pc->capacity = BASIC;
pc->sz = 0;
pc->data = (PeoInfo*)malloc(pc->capacity * sizeof(PeoInfo));
if (pc->data == NULL)
{
perror("init_contact:malloc");
return;
}
memset(pc->data,0, pc->capacity * sizeof(PeoInfo));
}
//检查通讯录大小是否已满,满则扩容
void check_capacity(Contact* pc)
{
assert(pc);
if (pc->sz == pc->capacity - 1)
{
PeoInfo* temp = realloc(pc->data, (pc->capacity + 2) * sizeof(PeoInfo));
if (temp == NULL)
{
perror("check_capacity:");
return;
}
else
{
pc->data = temp;
pc->capacity += 2;
}
}
}
//内存释放
void free_contact(Contact* pc)
{
assert(pc);
free(pc->data);
pc->data = NULL;
pc -> sz = 0;
pc -> capacity = 0;
}
//新增联系人信息
void add_contact(Contact* pc)
{
assert(pc);
check_capacity(pc);
printf("请输入姓名:");
scanf("%s", pc->data[pc->sz].name);
printf("请输入性别:");
scanf("%s", pc->data[pc->sz].sex);
printf("请输入年龄:");
scanf("%s", pc->data[pc->sz].age);
printf("请输入电话:");
scanf("%s", pc->data[pc->sz].tele);
printf("请输入住址:");
scanf("%s", pc->data[pc->sz].addr);
pc->sz++; //联系人数目变化
}
//打印通讯录
void print_contact(Contact* pc)
{
assert(pc);
printf("%-20s %-5s %-5s %-15s %-20s\n", "姓名", "性别", "年龄", "电话号码", "住址");
for (int i = 0; i < pc->sz; i++)
{
printf("%-20s %-5s %-5s %-15s %-20s\n", pc->data[i].name, pc->data[i].sex, pc->data[i].age, pc->data[i].tele, pc->data[i].addr);
}
printf("\n");
}
//查找是否有此联系人,有则返回下标
int find_name(Contact* pc, char* name)
{
assert(pc);
int ret = 0;
for (int i = 0; i < pc->sz; i++)
{
if (0 == strcmp(name, pc->data[i].name))
{
return i;
}
else if (i == pc->sz)
{
return -1;
}
}
return -1;
}
//删除指定联系人信息
void delete_contact(Contact* pc)
{
assert(pc);
char dname[NAME_MAX];
printf("请输入删除的联系人姓名:");
scanf("%s", dname);
if (find_name(pc, dname) != -1)
{
//用后一个联系人的信息替换掉前一个联系人的信息
for (int j = find_name(pc, dname); j < pc->sz - 1; j++)
{
pc->data[j] = pc->data[j + 1];
}
pc->sz--;
printf("删除成功\n\n");
}
else
{
printf("找不到该联系人\n\n");
}
}
//查找指定联系人信息
void search_contact(Contact* pc)
{
assert(pc);
char sname[NAME_MAX];
printf("请输入联系人姓名:");
scanf("%s", sname);
int ret = find_name(pc, sname);
if (ret != -1)
{
printf("%-20s %-5s %-5s %-15s %-20s\n", "姓名", "性别", "年龄", "电话号码", "住址");
printf("%-20s %-5s %-5s %-15s %-20s\n\n", pc->data[ret].name, pc->data[ret].sex, pc->data[ret].age, pc->data[ret].tele, pc->data[ret].addr);
}
else
{
printf("找不到此联系人\n\n");
}
}
//修改指定联系人信息
void modify_contact(Contact* pc)
{
assert(pc);
char mname[NAME_MAX];
printf("请输入需要修改的联系人:");
scanf("%s", mname);
int ret = find_name(pc, mname);
if (ret != -1)
{
printf("请输入新的联系人信息:\n");
printf("姓名:");
scanf("%s", pc->data[ret].name);
printf("性别:");
scanf("%s", pc->data[ret].sex);
printf("年龄:");
scanf("%s", pc->data[ret].age);
printf("电话:");
scanf("%s", pc->data[ret].tele);
printf("住址:");
scanf("%s", pc->data[ret].addr);
printf("修改成功\n\n");
}
else
{
printf("此联系人不存在\n\n");
}
}
//清空所有联系人
void clean_contact(Contact* pc)
{
assert(pc);
printf("请确认清空所有联系人:\n");
printf("1->YES 2->NO\n");
int judge = 0;
scanf("%d", &judge);
if (judge == 1)
{
free_contact(pc);
printf("已清空\n\n");
}
else
{
return;
}
}
//按名字排序联系人
void sort_contact(Contact* pc)
{
assert(pc);
int upordown = 0;
printf("请选择排序方式:\n");
printf("1->升序 2->降序\n");
scanf("%d", &upordown);
if (upordown == 1)
{
for (int i = 0; i < pc->sz - 1; i++)
for (int j = 0; j < pc->sz - 1 - i; j++)
{
if (strcmp(pc->data[j].name, pc->data[j + 1].name) > 0)
{
pc->data[pc->capacity - 1] = pc->data[j];
pc->data[j] = pc->data[j + 1];
pc->data[j + 1] = pc->data[pc->capacity - 1];
}
}
printf("已按姓名升序排列\n\n");
}
else if (upordown == 2)
{
for (int i = 0; i < pc->sz - 1; i++)
for (int j = 0; j < pc->sz - 1 - i; j++)
{
if (strcmp(pc->data[j].name, pc->data[j + 1].name) < 0)
{
pc->data[pc->capacity - 1] = pc->data[j];
pc->data[j] = pc->data[j + 1];
pc->data[j + 1] = pc->data[pc->capacity - 1];
}
}
printf("已按姓名降序排列\n\n");
}
else
{
printf("输入错误\n");
return;
}
}
主函数
#define _CRT_SECURE_NO_WARNINGS 1
#include"contact2.0.h"
void menu(void)
{
printf("*********CONTACT*********\n");
printf("*** 1.Add 2.Dele ***\n");
printf("*** 3.Search 4.Modify ***\n");
printf("*** 5.Print 6.Clean ***\n");
printf("*** 7.Sort 0.Exit ***\n");
printf("*************************\n");
}
void test(void)
{
int input = 0;
Contact con; //创建通讯录
init_contact(&con); //初始化
do
{
menu();
printf("请选择:");
scanf("%d", &input);
switch (input)
{
case ADD:
add_contact(&con);
break;
case DELE:
delete_contact(&con);
break;
case SEARCH:
search_contact(&con);
break;
case MODIFY:
modify_contact(&con);
break;
case PRINT:
print_contact(&con);
break;
case CLEAN:
clean_contact(&con);
break;
case SORT:
sort_contact(&con);
break;
case EXIT:
free_contact(&con);
break;
default:
printf("选择错误\n");
break;
}
} while (input);
}
int main()
{
test();
return 0;
}