通讯录功能
增加、删除、查找、修改联系人,打印所有联系人,清空所有联系人
#define _CRT_SECURE_NO_WARNINGS 1
#ifndef _ADDRESSLIST_H_
#define _ADDRESSLIST_H_
#include<stdio.h>
#include<stdlib.h>
#include<memory.h>
#include<string.h>
//存放联系人姓名号码的结构体,如果还想加其他的信息可以自行添加
typedef struct Addresslist {
char name[1024];
char phone[1024];
}Addresslist;
//充当电话簿的结构体
typedef struct Book {
Addresslist num[200];
unsigned int count;
}Book;
int menu();//菜单打印函数
void InitList(Book* plist);//初始化通讯录
void Add(Book* plist);//添加联系人
void PrintAll(Book* plist);//打印所有联系人
void Delete(Book* plist);//删除联系人
void Find(Book* plist);//查找联系人
void Amend(Book* plist);//修改联系人
void CleanAll(Book* plist);//清除所有联系人
#endif // !_ADDRESSLIST_H_
功能实现
//addresslist.c
#define _CRT_SECURE_NO_WARNINGS 1
#include"addresslist.h"
//功能菜单
int menu() {
int choice = 0;
printf("请选择:\n");
printf("***********************************************\n");
printf("**************** 1.增加联系人 *****************\n");
printf("**************** 2.删除联系人 *****************\n");
printf("**************** 3.查找联系人 *****************\n");
printf("**************** 4.更改联系人资料 *************\n");
printf("**************** 5.显示所有联系人 *************\n");
printf("**************** 6.清空所有联系人 *************\n");
printf("**************** 0.退出 ***********************\n");
printf("***********************************************\n");
scanf("%d", &choice);
return choice;
}
//初始化联系人列表
void InitList(Book* plist) {
plist->count = 0 ;
memset(plist->num, 0, sizeof(plist->num));
//打印联系人
void PrintAll(Book* plist) {
unsigned int i = 0;
printf("通讯录\n");
for (i = 0; i < (plist->count); i++) {
printf("姓名:%s\n", plist->num[i].name);
printf("电话号码:%s\n", plist->num[i].phone);
}
}
//添加联系人
void Add(Book* plist) {
printf("联系人姓名:\n");
scanf("%s", plist->num[plist->count].name);//输入姓名
printf("联系人号码:\n");
scanf("%s", plist->num[plist->count].phone);//输入号码
if ( (plist->count) > 200) {
printf("联系人达到上限\n");
}
else {
plist->count++;
}
}
//查找函数
static int Findname(char* pname, Book* plist) {
unsigned int i = 0;
for (i = 0; i < (plist->count); i++) {
int ret = strcmp(pname, plist->num[i].name);
if (ret == 0) {
return i;
}
}
return -1;
}
//删除联系人
void Delete(Book* plist) {
char name[1024] = { 0 };
int choice = 0;
printf("输入要删除的联系人姓名:\n");
scanf("%s", name);
printf("确定要删除联系人吗?\n");
printf("1.是 0.否\n");
scanf("%d", &choice);
if (choice) {
int num = Findname(name, plist);
if (num >= 0) {
unsigned int i = 0;
for (i = num; i < plist->count; i++) {
plist->num[num + i] = plist->num[num + i + 1];
}
plist->count--;
printf("删除成功\n");
}
else
printf("找不到联系人\n");
}
else
printf("返回主菜单\n");
}
//查找联系人
void Find( Book* plist) {
char name[1024] = { 0 };
printf("待查找联系人姓名:\n");
scanf("%s", name);
int num = Findname(name, plist);
if (num != -1) {
printf("找到了");
printf("姓名 :%s\n", plist->num[num].name);
printf("号码:%s\n", plist->num[num].phone);
}
else
printf("找不到联系人。\n");
}
//修改联系人
void Amend(Book* plist) {
char name[1024] = { 0 };
printf("待修改联系人姓名:\n");
scanf("%s", name);
int num = Findname(name, plist);
if (num != -1) {
printf("请重新输入联系人信息\n");
printf("联系人姓名:\n");
scanf("%s", plist->num[num].name);
printf("联系人号码:\n");
scanf("%s", plist->num[num].phone);
printf("修改成功\n");
printf("姓名:%s\n", plist->num[num].name);
printf("号码:%s\n", plist->num[num].phone);
}
else
printf("找不到联系人\n");
}
//清除通讯录
void CleanAll(Book* plist) {
int choice = 0;
printf("确定要删除所有联系人吗?\n");
printf("1.是 0.否");
scanf("%d", &choice);
if (choice) {
unsigned int i = 0;
for (i = 0; i < plist->count; i++) {
*plist->num[i].name = 0;
*plist->num[i].phone = 0;
}
}
}
主函数(创建转移表)
//main.c
#include"addresslist.h"
int main()
{
Book list;
//转移表
void(*pfun[7])(Book* p2) = {0, Add, Delete, Find, Amend, PrintAll, CleanAll};
InitList(&list);
int ret = 0;
do {
ret = menu();//ret为用户选择的功能对应的数字
if (ret == 0)
break;
if (ret < 1 || ret > 6) {
printf("请输入有效值:\n");
continue;
}
else {
(*pfun[ret])(&list);
PrintAll(&list);
printf("\n");
}
} while (ret);
system("pause");
return 0;
}
总结
转移表
void(*pfun[7])(Book* p2) = {0, Add, Delete, Find, Amend, PrintAll, CleanAll};
这里创建了一个存放函数指针的数组,函数名即函数指针,为了对应menu的顺序,将函数指针数组的首元素初始化为0,后面依次对应相应的功能。
需要注意,转移表中所有函数的返回值类型,参数类型都要完全一致。
转移表的优势
如果需要增加或者减少一些功能,在实现相应的函数后,只需在转移表中加入函数名即可添加功能。而不用像使用switch语句一样添加几个功能就要添加几个case,从而简化了代码的结构。