应用实现一个通讯录:
通讯录可以用来存储100个人的信息,每个人的信息包括:姓名、性别、年龄、电话、住址
通讯录实现的功能包括:
- 添加联系人信息
- 删除指定联系人信息
- 查找指定联系人信息
- 修改指定联系人信息
- 显示所有联系人信息
- 清空所有联系人
- 以名字排序所有联系人
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");
printf("*******************************\n");
printf("*******************************\n");
}
int main()
{
do
{
menu();
printf("请选择:>");
scanf("%d", &input);
switch (input)
{
case 1:
break;
case 2:
break;
case 3:
break;
case 4:
break;
case 5:
break;
case 6:
break;
case 0:
break;
default:
break;
}
} while (input);
return 0;
}
1.根据通讯录实现的功能首先写一个菜单和循环的框架,以便设计实现各种功能的函数。
2.通讯录需要里个人的信息要包含姓名、性别、年龄、电话、住址等,需要声明一个结构体类型用来存放个人信息;同时通讯录里需要显示共有多少人,以便于方便对联系人进行增删查改;所以一个通讯录至少需要包含一个存放个人信息的结构体类型数组和通讯录联系人数:
#define MAX_NAME 20
#define MAX_SEX 6
#define MAX_TELE 12
#define MAX_ADDR 30 //定义宏更能灵活改动各种数据大小
#define MAX 100
//通讯录
struct Stu
{
char name[MAX_NAME];
char sex[MAX_SEX];
int age;
char tele[MAX_TELE];
char addr[MAX_ADDR];
};
struct Contact
{
struct Stu Data[MAX];
int sz;
};
3.此时就需要在主函数里创建通讯录并将其初始化
//创建通讯录
struct Contact con;
//初始化通讯录
InitContct(&con);
这里初始化通讯录需要自定义一个函数,将通讯录变量的地址作为参数可以对通讯录中的内容进行修改,初始化方式如下:
void InitContct(struct Contact* pc)
{
assert(pc);
memset(pc->Data, 0, MAX * sizeof(struct Stu));
pc->sz = 0;
}
避免传递空指针,这里可以用assert断言一下;内存设置函数memset将结构体成员中的Data变量的所有字节都初始化为了0;此时通讯录中无联系人,结构体成员中的联系人人数也被初始化为0;
4.通讯录与界面框架实现好了,就可以自定义函数一一实现通讯录中增删查改等各种功能,首先我们来实现添加联系人的功能:
void AddContact(struct Contact* pc)
{
//添加联系人
assert(pc);
if (pc->sz > MAX)
{
printf("通讯录成员已满,添加失败\n");
return;
}
printf("请输入名字:>");
scanf("%s", pc->Data[pc->sz].name);
printf("请输入性别:>");
scanf("%s", pc->Data[pc->sz].sex);
printf("请输入年龄:>");
scanf("%d", &pc->Data[pc->sz].age);
printf("请输入电话:>");
scanf("%s", pc->Data[pc->sz].tele);
printf("请输入地址:>");
scanf("%s", pc->Data[pc->sz].addr);
pc->sz++;
printf("成功添加联系人\n");
}
添加联系人的时候,要考虑通讯录中成员是否已满,如果满了就不能添加新的联系人了,所以需要判断一下,满人就直接返回,如果联系人没有满,就可以开开心心的添加新的联系人了,增加新的联系人同时也需要将联系人人数加一,便于对通讯录的管理,添加完以后我们就可以通过实现显示功能看到我们添加的联系人:
void ShowContact(const struct Contact* pc)
{
int i = 0;
printf("%-20s\t %-6s\t %-5s\t %-12s\t %-30s\n", "姓名", "性别", "年龄", "电话", "地址");
for (i = 0; i < pc->sz; i++)
{
printf("%-20s\t %-6s\t %-5d\t %-12s\t %-30s\n", pc->Data[i].name,
pc->Data[i].sex,
pc->Data[i].age,
pc->Data[i].tele,
pc->Data[i].addr);
}
}
显示联系人主要是通过遍历Data数组来一一打印个人信息,这里需要多加注意打印格式的调整,比如都调整成左对齐,各种数据占等距的空间,不然打印出来会乱糟糟的影响数据的可读性,可以将首行打印为信息栏,方便大家了解是什么信息:
printf("%-20s\t %-6s\t %-5s\t %-12s\t %-30s\n", "姓名", "性别", "年龄", "电话", "地址");
接下来我们实现删除功能,要删除通讯录中的某个联系人,要先将这个人在联系人列表中找到,这里我们可以创建一个通过名字查找的函数:
//查找通讯录联系人是否存在
static int FindByName(const struct Contact* pc,char name[])
{
int i = 0;
for (i = 0; i < pc->sz; i++)
{
if (0 == strcmp(pc->Data[i].name, name))
{
return i;
}
}
return -1;
}
利用字符串比较函数对要删除的名字和通讯录中的名字进行比较,如果找不到就不能进行删除操作,如果找到了,我们可以通过这个联系人在通讯录列表中的序列将其删除,为了保持数据排列的有序性,删除人后面的联系人都要向前一个人处覆盖一下,同时通讯录中联系人数也要减一:
void DelContact(struct Contact* pc)
{
//删除联系人
char name[MAX_NAME];
printf("请输入姓名;>");
scanf("%s", &name);
int ret = FindByName(pc,name);
if (-1 == ret)
{
printf("删除成员不存在\n");
}
else
{
//删除成员
int j = 0;
for (j = ret; j < pc->sz - 1; j++)
{
pc->Data[j] = pc->Data[j + 1];
}
pc->sz--;
printf("删除成功\n");
}
}
同样的,实现查找功能和修改功能都需要先在通讯录中查找有没有这个人,都需要调用FindByName函数:
void SearchContact(const struct Contact* pc)
{
//查找函数
char name[MAX_NAME];
printf("请输入要查找的名字\n");
scanf("%s", name);
int ret=FindByName(pc, name);
if (-1 == ret)
printf("通讯录中不存在该成员\n");
else
{
printf("查找成功\n");
printf("%-20s\t %-6s\t %-5s\t %-12s\t %-30s\n", "姓名", "性别", "年龄", "电话", "地址");
printf("%-20s\t %-6s\t %-5d\t %-12s\t %-30s\n", pc->Data[ret].name,
pc->Data[ret].sex,
pc->Data[ret].age,
pc->Data[ret].tele,
pc->Data[ret].addr);
}
}
查找函数不需要对结构体进行修改,所以在结构体指针这个形参前面加上const更安全,查找到以后需要调取这个人的信息打印一下,像显示函数一样,我们在打印时需要注意格式,增加可读性。
void ModifyContact(struct Contact* pc)
{
//修改通讯录
char name[MAX_NAME];
printf("请输入要修改的名字\n");
scanf("%s", name);
int ret = FindByName(pc, name);
if (-1 == ret)
printf("通讯录中不存在该成员\n");
else
{
printf("请输入名字:>");
scanf("%s", pc->Data[ret].name);
printf("请输入性别:>");
scanf("%s", pc->Data[ret].sex);
printf("请输入年龄:>");
scanf("%d", &pc->Data[ret].age);
printf("请输入电话:>");
scanf("%s", pc->Data[ret].tele);
printf("请输入地址:>");
scanf("%s", pc->Data[ret].addr);
printf("修改成功\n");
}
修改通讯录同添加通讯录成员类似,仅多了查找的功能;
对通讯录中的联系人我们可以进行排序,利用qsort函数,可以快速将联系人用各种变量类型进行排序,通常用名字进行排序的居多,这里实现以下:
int CmpByName(const void* e1, const void* e2)
{
return strcmp(((struct Stu*)e1)->name,((struct Stu*)e2)->name);
}
void SortByName(struct Contact* pc)
{
qsort(pc->Data, pc->sz, sizeof(struct Stu), CmpByName);
}
也可以用年龄进行排序:
int CmpByAge(const void* e1, const void* e2)
{
return ((struct Stu*)e1)->age - ((struct Stu*)e2)->age;
}
void SortByName(struct Contact* pc)
{
qsort(pc->Data, pc->sz, sizeof(struct Stu), CmpByAge);
}
应用结构体实现通讯录的源码如下:
contact.h
#pragma once
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
#define MAX_NAME 20
#define MAX_SEX 6
#define MAX_TELE 12
#define MAX_ADDR 30
#define MAX 100
//通讯录
struct Stu
{
char name[MAX_NAME];
char sex[MAX_SEX];
int age;
char tele[MAX_TELE];
char addr[MAX_ADDR];
};
struct Contact
{
struct Stu Data[MAX];
int sz;
};
//初始化通讯录
void InitContct(struct Contact* pc);
//添加通讯录成员
void AddContact(struct Contact* pc);
//删除通讯录成员
void DelContact(struct Contact* pc);
//查找通讯录成员
void SearchContact(const struct Contact* pc);
//修改通讯录成员
void ModifyContact(struct Contact* pc);
//显示通讯录
void ShowContact(const struct Contact* pc);
//通过名字查找通讯录成员
void SortByName(struct Contact* pc);
contact.c
#define _CRT_SECURE_NO_WARNINGS 1
#include "contact.h"
void InitContct(struct Contact* pc)
{
assert(pc);
memset(pc->Data, 0, MAX * sizeof(struct Stu));
pc->sz = 0;
}
void AddContact(struct Contact* pc)
{
assert(pc);
if (pc->sz > MAX)
{
printf("通讯录成员已满,添加失败\n");
return;
}
printf("请输入名字:>");
scanf("%s", pc->Data[pc->sz].name);
printf("请输入性别:>");
scanf("%s", pc->Data[pc->sz].sex);
printf("请输入年龄:>");
scanf("%d", &pc->Data[pc->sz].age);
printf("请输入电话:>");
scanf("%s", pc->Data[pc->sz].tele);
printf("请输入地址:>");
scanf("%s", pc->Data[pc->sz].addr);
pc->sz++;
printf("成功添加联系人\n");
}
void ShowContact(const struct Contact* pc)
{
int i = 0;
printf("%-20s\t %-6s\t %-5s\t %-12s\t %-30s\n", "姓名", "性别", "年龄", "电话", "地址");
for (i = 0; i < pc->sz; i++)
{
printf("%-20s\t %-6s\t %-5d\t %-12s\t %-30s\n", pc->Data[i].name,
pc->Data[i].sex,
pc->Data[i].age,
pc->Data[i].tele,
pc->Data[i].addr);
}
}
//查找通讯录联系人是否存在
static int FindByName(const struct Contact* pc,char name[])
{
int i = 0;
for (i = 0; i < pc->sz; i++)
{
if (0 == strcmp(pc->Data[i].name, name))
{
return i;
}
}
return -1;
}
void DelContact(struct Contact* pc)
{
char name[MAX_NAME];
printf("请输入姓名;>");
scanf("%s", &name);
int ret = FindByName(pc,name);
if (-1 == ret)
{
printf("删除成员不存在\n");
}
else
{
//删除成员
int j = 0;
for (j = ret; j < pc->sz - 1; j++)
{
pc->Data[j] = pc->Data[j + 1];
}
pc->sz--;
printf("删除成功\n");
}
}
void SearchContact(const struct Contact* pc)
{
char name[MAX_NAME];
printf("请输入要查找的名字\n");
scanf("%s", name);
int ret=FindByName(pc, name);
if (-1 == ret)
printf("通讯录中不存在该成员\n");
else
{
printf("查找成功\n");
printf("%-20s\t %-6s\t %-5s\t %-12s\t %-30s\n", "姓名", "性别", "年龄", "电话", "地址");
printf("%-20s\t %-6s\t %-5d\t %-12s\t %-30s\n", pc->Data[ret].name,
pc->Data[ret].sex,
pc->Data[ret].age,
pc->Data[ret].tele,
pc->Data[ret].addr);
}
}
void ModifyContact(struct Contact* pc)
{
char name[MAX_NAME];
printf("请输入要修改的名字\n");
scanf("%s", name);
int ret = FindByName(pc, name);
if (-1 == ret)
printf("通讯录中不存在该成员\n");
else
{
printf("请输入名字:>");
scanf("%s", pc->Data[ret].name);
printf("请输入性别:>");
scanf("%s", pc->Data[ret].sex);
printf("请输入年龄:>");
scanf("%d", &pc->Data[ret].age);
printf("请输入电话:>");
scanf("%s", pc->Data[ret].tele);
printf("请输入地址:>");
scanf("%s", pc->Data[ret].addr);
printf("修改成功\n");
}
}
int CmpByName(const void* e1, const void* e2)
{
return strcmp(((struct Stu*)e1)->name,((struct Stu*)e2)->name);
}
int CmpByAge(const void* e1, const void* e2)
{
return ((struct Stu*)e1)->age - ((struct Stu*)e2)->age;
}
void SortByName(struct Contact* pc)
{
qsort(pc->Data, pc->sz, sizeof(struct Stu), CmpByName);
//qsort(pc->Data, pc->sz, sizeof(struct Stu), CmpByAge);
}
text.c
#define _CRT_SECURE_NO_WARNINGS 1
#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");
printf("*******************************\n");
printf("*******************************\n");
}
int main()
{
int input;
//创建通讯录
struct Contact con;
//初始化通讯录
InitContct(&con);
do
{
menu();
printf("请选择:>");
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:
SortByName(&con);
break;
case 0:
printf("已退出\n");
break;
default:
printf("选择错误\n");
break;
}
} while (input);
return 0;
}