C语言之通讯录的模拟实现

  在C语言学习结束之际,谨以此篇文章来对C语言的学习告一段落。

纲要:

  • 通讯录的静态版本
  • 通讯录的动态版本
  • 通讯录的带文件版本

  因为三种实现方法除了储存形式不同,其他都基本相同,所以我们重点论述静态版本的实现,以及它们不同的储存方式。


一.通讯录的静态版本  

  为什么叫它为静态版本呢,因为在此部分的储存是以数组来储存的,那对于各种各样的信息,我们要拿什么数组来存放它呢?当然是结构体数组了,所以我们来定义一个结构体来表示个人信息:

//采用宏的目的是方便日后修改
#define NAME_MAX 20
#define SEX_MAX 5
#define PNUM_MAX 13
#define ADDR_MAX 20
#define MAX 10 //存放个人信息的结构体
typedef struct Data
{
char name[NAME_MAX];//姓名
int age;//年龄
char sex[SEX_MAX];//性别
char pnum[PNUM_MAX];//电话
char addr[ADDR_MAX];//地址
} Data;

  现在有了个人信息的结构体,我们需要再来一个结构体来存放它的数组及数组内有效信息的个数,即:

//存放MAX个个人信息的通讯录
typedef struct Contact
{
Data data[MAX];
int size;
} Contact;

  那么,准备工作做好之后,我们就开始正式实现了,首先我们肯定是要先创建一个通讯录,这时我们再来想一想,我们就这样创建之后,我们是否可以直接使用呢?

  对此我们来看一张图片:

  我们发现,现在它里面都放着一些随机值,所以我们需要将其初始化一下,来方便我们的使用:

void ContactInit(Contact *p)
{
//保证p不为NULL
assert(p);
//置零
memset(p->data, 0, sizeof(p->data));
p->size = 0; }

  我们再来看一下结果:

  我们发现,现在它内部已经被我们置为了0;接着我们做的就是添加联系人了,不过在此之前,我们不妨先做一个菜单来显示我们都有一些什么功能:

void menu()
{
//打印菜单
printf("******************************************\n");
printf("****** 1.add 2.del ******\n");
printf("****** 3.search 4.modify ******\n");
printf("****** 5.show 6.sort ******\n");
printf("****** 7.help 0.exit ******\n");
printf("******************************************\n");
}

  接着是我们的帮助选项:

//打印帮助信息
void ContactHelp(Contact *p)
{
printf("*******************************************\n");
printf("****** add ---- 添加联系人信息 ******\n");
printf("****** del ---- 删除联系人信息 ******\n");
printf("****** search ---- 查找联系人信息 ******\n");
printf("****** modify ---- 修改联系人信息 ******\n");
printf("****** show ---- 展示联系人信息 ******\n");
printf("****** help ---- 帮助信息 ******\n");
printf("****** sort ---- 排序联系人信息 ******\n");
printf("****** exit ---- 退出通讯录 ******\n");
printf("*******************************************\n");
}

  以及我们来用枚举来定义一些常量,方便在switch()结构中 来辨别它走了哪条路线:

//枚举来作为常量使得在看代码时比较清晰
enum choice
{
EXIT,
ADD,
DEL,
SEARCH,
MODIFY,
SHOW,
SORT,
HELP
};

  以及写出我们的选择结构:我们采用do-while循环

void test()
{
Contact list;//定义一个通讯录
Contact *p = &list;//赋址 //初始化
ContactInit(p);
int input = 0;
do
{
menu();
printf("请输入你的选择:> ");
scanf("%d", &input);
switch (input)
{
case ADD:
ContactAdd(p);
break;
case DEL:
ContactDel(p);
break;
case SEARCH:
ContactSearch(p);
break;
case MODIFY:
ContactModify(p);
break;
case SHOW:
ContactShow(p);
break;
case SORT:
ContactSort(p);
break;
case HELP:
ContactHelp(p);
break;
case EXIT:
ContactExit(p);
break;
default:
printf("输入非法!"); } } while (input); }

  这样的好处是当用户输入0时循环便自己停止,不用我们再次去判断当用户输入0时我们要退出的问题,接下来我们就来填写我们函数的内容了:

  1.添加联系人

//添加联系人
void ContactAdd(Contact *p)
{
//断言保证p不为NULL
assert(p);
//如果联系人容量已经等于最大容量了
if(p->size==MAX)
{
printf("通讯录已满,请删除一些后继续添加!\n");
return ;
}
Data person;//记录联系人信息
printf("请输入联系人的姓名:>");
scanf("%s", person.name);
printf("请输入联系人的年龄:>");
scanf("%d", &person.age);
printf("请输入联系人的性别:>");
scanf("%s", person.sex);
printf("请输入联系人的电话:>");
scanf("%s", person.pnum);
printf("请输入联系人的住址:>");
scanf("%s", person.addr);
//将联系人信息存到通讯录中
p->data[p->size] = person;
p->size++;
}

  我们要是观察到我们输入的信息,最好就是把我们所输入的信息给打印出来:

  2.展示联系人

//展示联系人信息
void ContactShow(Contact *p)
{
if (p->size == 0)
{
printf("通讯录中并无一人!\n");
     return ; 
}
int i = 0;
printf(" 姓名\t性别\t 年龄\t 电话\t\t地址\n");
for (i = 0; i < p->size; i++)
{
printf(" %-5s\t%s\t%d\t%s\t%s\n", p->data[i].name,
p->data[i].sex,
p->data[i].age,
p->data[i].pnum,
p->data[i].addr); }
}

  测试结果:

  接下来就是删除联系人了

  3.删除联系人

    首先删除联系人肯定需要查找信息,又因为后面的几个函数也要用到它,所以我们单独来写一个查找模块:

//查找模块
int ContactFind(Contact *p, char *FindData)
{
assert(p);
int i = 0;
for (i = 0; i < p->size; i++)
{
if (strcmp(p->data[i].name, FindData) == 0)
{
return i;//找到就返回下标
}
}
return -1;//找不到就返回-1
}

  删除:

//删除联系人
void ContactDel(Contact *p)
{
assert(p);
char DelName[NAME_MAX] = {0};
printf("请输入你要删除的联系人姓名:>");
scanf("%s", DelName);
int ret = ContactFind(p, DelName);
if (ret == -1)
{
printf("通讯录中并无此人,请重新检查输入!\n");
} else
{
int j = 0;
for (j = ret; j < p->size; j++)
{
//从前往后依次挪动覆盖
p->data[j] = p->data[j + 1];
}
//删除完成之后,联系人个数减一
p->size--;
}
}

  4.查找联系人信息

//查找联系人
void ContactSearch(Contact *p)
{
assert(p);
char SearchName[NAME_MAX];
printf("请输入你要查找的联系人姓名:>\n");
scanf("%s",SearchName);
//查找有无此人
int ret = ContactFind(p,SearchName);
if (ret == -1)
{
printf("通讯录中并无此人,请重新检查输入!\n");
} else
{
printf("你所查找的联系人信息为:\n");
printf(" 姓名\t性别\t 年龄\t 电话\t\t地址\n");
printf(" %-5s\t%s\t%d\t%s\t%s\n", p->data[ret].name,
p->data[ret].sex,
p->data[ret].age,
p->data[ret].pnum,
p->data[ret].addr);
}
}

  5.修改联系人信息

//修改联系人信息
void ContactModify(Contact *p)
{
assert(p);
char ModifyName[NAME_MAX];
printf("请输入你要修改的联系人姓名:>");
scanf("%s",ModifyName);
int ret = ContactFind(p,ModifyName);
if (ret == -1)
{
printf("通讯录中并无此人,请重新检查输入!\n");
} else
{
Data person;//记录联系人信息
printf("请输入联系人的姓名:>");
scanf("%s", person.name);
printf("请输入联系人的年龄:>");
scanf("%d", &person.age);
printf("请输入联系人的性别:>");
scanf("%s", person.sex);
printf("请输入联系人的电话:>");
scanf("%s", person.pnum);
printf("请输入联系人的住址:>");
scanf("%s", person.addr);
//将联系人信息存到通讯录中
p->data[ret] = person;
}
}

  6.排序联系人 --- 我们使用 qsort 来排序

enum sort_by
{
NAME=1,
SEX,
AGE,
PNUM,
ADDR
};
void sort_menu()
{
printf(" SORT_MENU \n");
printf("******************************\n");
printf("**** 1.name ****\n");
printf("**** 2.sex ****\n");
printf("**** 3.age ****\n");
printf("**** 4.pnum ****\n");
printf("**** 5.addr ****\n");
printf("******************************\n");
} int sort_by_name(const void *s1, const void *s2)
{
return strcmp(((Data *) s1)->name, ((Data *) s2)->name);
} int sort_by_sex(const void *s1, const void *s2)
{
return strcmp(((Data *) s1)->sex, ((Data *) s2)->sex);
} int sort_by_age(const void *s1, const void *s2)
{
return ((Data *) s1)->age - ((Data *) s2)->age;
} int sort_by_pnum(const void *s1, const void *s2)
{
return strcmp(((Data *) s1)->pnum, ((Data *) s2)->pnum);
} int sort_by_addr(const void *s1, const void *s2)
{
return strcmp(((Data *) s1)->addr, ((Data *) s2)->addr);
} //排序联系人
void ContactSort(Contact *p)
{
assert(p);
int choice;
sort_menu();
printf("请选择排序的参考量:>");
scanf("%d", &choice);
switch (choice)
{
case NAME:
qsort(p->data, p->size, sizeof(Data), sort_by_name);
break;
case SEX:
qsort(p->data, p->size, sizeof(Data), sort_by_sex);
break;
case AGE:
qsort(p->data, p->size, sizeof(Data), sort_by_age);
break;
case PNUM:
qsort(p->data, p->size, sizeof(Data), sort_by_pnum);
break;
case ADDR:
qsort(p->data, p->size, sizeof(Data), sort_by_addr);
break;
default:
printf("输入有误,请检查输入!\n");
}
}

到这,我们的静态通讯录就完了,但是我们仍可对用户操作优化一下,如:及时的清屏等,以及暂停:

例:

    do
{
menu();
printf("请输入你的选择:>");
scanf("%d", &input);
system("cls");
switch (input)
{
case QUIT:
printf("退出通讯录!\n");
break;
case ADD:
add(p);
system("pause");
system("cls");
break;
case DEL:
del(p);
system("pause");
system("cls");
break;
case SEARCH:
search(p);
system("pause");
system("cls");
break;
case MODIFY:
modify(p);
system("pause");
system("cls");
break;
case SHOW:
show(p);
system("pause");
system("cls");
break;
case SORT:
sort(p);
system("pause");
system("cls");
break;
case HELP:
help();
system("pause");
system("cls");
break;
default:
printf("非法输入,请检查输入!\n");
system("pause");
system("cls");
break;
}
} while (input);

  这样我们的界面看起来就干净多了,但是有没有发现,我们为了达到这个效果,我们写了很多重复的代码!

  那这样我们应该怎么办呢 --- 还记得我们之前所提到的函数指针数组吗?

void test2()
{
Contact list;//定义一个通讯录
Contact *p = &list;//赋址
//初始化
ContactInit(p);
//用一个函数指针数组来存放函数指针
void (*fun[])(Contact *) ={ContactExit,
ContactAdd,
ContactDel,
ContactSearch,
ContactModify,
ContactShow,
ContactSort,
ContactHelp};
int input = 0;//存放用户选择的信息
do{
menu();
printf("请输入你的选择:>");
scanf("%d", &input);
system("cls");
if(input>=0&&input<=sizeof(fun))
{
fun[input](p);
system("cls");
}
else
{
system("cls");
printf("输入非法,请检查输入!\n");
}
}while(input);
}

  这样是不是代码就少了很多!

所以完整代码如下:

//确保文件只包含一次
#ifndef CONTACT_CONTACT_H
#define CONTACT_CONTACT_H #include <stdio.h>
#include <string.h>
#include <errno.h>
#include <stdlib.h>
#include <assert.h> //采用宏的目的是方便日后修改
#define NAME_MAX 20
#define SEX_MAX 8
#define PNUM_MAX 13
#define ADDR_MAX 20
#define MAX 10 //存放个人信息的结构体
typedef struct Data
{
char name[NAME_MAX];//姓名
int age;//年龄
char sex[SEX_MAX];//性别
char pnum[PNUM_MAX];//电话
char addr[ADDR_MAX];//地址
} Data; //存放MAX个个人信息的通讯录
typedef struct Contact
{
Data data[MAX];
int size;
} Contact; //枚举来作为常量使得在看代码时比较清晰
enum choice
{
EXIT,
ADD,
DEL,
SEARCH,
MODIFY,
SHOW,
SORT,
HELP
}; enum sort_by
{
NAME=1,
SEX,
AGE,
PNUM,
ADDR
}; //初始化通讯录
void ContactInit(Contact *p); //添加联系人
void ContactAdd(Contact* p); //删除联系人
void ContactDel(Contact* p); //查找联系人
void ContactSearch(Contact* p); //修改联系人信息
void ContactModify(Contact* p); //展示联系人信息
void ContactShow(Contact* p); //排序联系人
void ContactSort(Contact* p); //打印帮助
void ContactHelp(Contact* p); //退出通讯录
void ContactExit(Contact* p); #endif //CONTACT_CONTACT_H

Contact.h

#include "Contact.h"
// 强调!!!
//调试请加setbuf(stdout,NULL)!!! //查找模块
int ContactFind(Contact *p, char *FindData)
{
assert(p);
int i = 0;
for (i = 0; i < p->size; i++)
{
if (strcmp(p->data[i].name, FindData) == 0)
{
return i;//找到就返回下标
}
}
return -1;//找不到就返回-1
} void ContactInit(Contact *p)
{
//保证p不为NULL
assert(p);
//置零
memset(p->data, 0, sizeof(p->data));
p->size = 0; } //添加联系人
void ContactAdd(Contact *p)
{
//断言保证p不为NULL
assert(p);
//如果联系人容量已经等于最大容量了
if (p->size == MAX)
{
printf("通讯录已满,请删除一些后继续添加!\n");
return;
}
Data person;//记录联系人信息
printf("请输入联系人的姓名:>");
scanf("%s", person.name);
printf("请输入联系人的年龄:>");
scanf("%d", &person.age);
printf("请输入联系人的性别:>");
scanf("%s", person.sex);
printf("请输入联系人的电话:>");
scanf("%s", person.pnum);
printf("请输入联系人的住址:>");
scanf("%s", person.addr);
//将联系人信息存到通讯录中
p->data[p->size] = person;
p->size++;
} //删除联系人
void ContactDel(Contact *p)
{
assert(p);
char DelName[NAME_MAX] = {0};
printf("请输入你要删除的联系人姓名:>");
scanf("%s", DelName);
int ret = ContactFind(p, DelName);
if (ret == -1)
{
printf("通讯录中并无此人,请重新检查输入!\n");
} else
{
int j = 0;
for (j = ret; j < p->size; j++)
{
//从前往后依次挪动覆盖
p->data[j] = p->data[j + 1];
}
//删除完成之后,联系人个数减一
p->size--;
}
} //查找联系人
void ContactSearch(Contact *p)
{
assert(p);
char SearchName[NAME_MAX];
printf("请输入你要查找的联系人姓名:>");
scanf("%s", SearchName);
//查找有无此人
int ret = ContactFind(p, SearchName);
if (ret == -1)
{
printf("通讯录中并无此人,请重新检查输入!\n");
} else
{
printf("你所查找的联系人信息为:\n");
printf(" 姓名\t性别\t 年龄\t 电话\t\t地址\n");
printf(" %-5s\t%s\t%d\t%s\t%s\n", p->data[ret].name,
p->data[ret].sex,
p->data[ret].age,
p->data[ret].pnum,
p->data[ret].addr);
}
} //修改联系人信息
void ContactModify(Contact *p)
{
assert(p);
char ModifyName[NAME_MAX];
printf("请输入你要修改的联系人姓名:>");
scanf("%s", ModifyName);
int ret = ContactFind(p, ModifyName);
if (ret == -1)
{
printf("通讯录中并无此人,请重新检查输入!\n");
} else
{
Data person;//记录联系人信息
printf("请输入联系人的姓名:>");
scanf("%s", person.name);
printf("请输入联系人的年龄:>");
scanf("%d", &person.age);
printf("请输入联系人的性别:>");
scanf("%s", person.sex);
printf("请输入联系人的电话:>");
scanf("%s", person.pnum);
printf("请输入联系人的住址:>");
scanf("%s", person.addr);
//将联系人信息存到通讯录中
p->data[ret] = person;
}
} //展示联系人信息
void ContactShow(Contact *p)
{
if (p->size == 0)
{
printf("通讯录中并无一人!\n");
return;
} int i = 0;
printf(" 姓名\t性别\t 年龄\t 电话\t\t地址\n");
for (i = 0; i < p->size; i++)
{
printf(" %-5s\t%s\t%d\t%s\t%s\n", p->data[i].name,
p->data[i].sex,
p->data[i].age,
p->data[i].pnum,
p->data[i].addr); }
} void sort_menu()
{
printf(" SORT_MENU \n");
printf("******************************\n");
printf("**** 1.name ****\n");
printf("**** 2.sex ****\n");
printf("**** 3.age ****\n");
printf("**** 4.pnum ****\n");
printf("**** 5.addr ****\n");
printf("******************************\n");
} int sort_by_name(const void *s1, const void *s2)
{
return strcmp(((Data *) s1)->name, ((Data *) s2)->name);
} int sort_by_sex(const void *s1, const void *s2)
{
return strcmp(((Data *) s1)->sex, ((Data *) s2)->sex);
} int sort_by_age(const void *s1, const void *s2)
{
return ((Data *) s1)->age - ((Data *) s2)->age;
} int sort_by_pnum(const void *s1, const void *s2)
{
return strcmp(((Data *) s1)->pnum, ((Data *) s2)->pnum);
} int sort_by_addr(const void *s1, const void *s2)
{
return strcmp(((Data *) s1)->addr, ((Data *) s2)->addr);
} //排序联系人
void ContactSort(Contact *p)
{
assert(p);
int choice;
sort_menu();
printf("请选择排序的参考量:>");
scanf("%d", &choice);
switch (choice)
{
case NAME:
qsort(p->data, p->size, sizeof(Data), sort_by_name);
break;
case SEX:
qsort(p->data, p->size, sizeof(Data), sort_by_sex);
break;
case AGE:
qsort(p->data, p->size, sizeof(Data), sort_by_age);
break;
case PNUM:
qsort(p->data, p->size, sizeof(Data), sort_by_pnum);
break;
case ADDR:
qsort(p->data, p->size, sizeof(Data), sort_by_addr);
break;
default:
printf("输入有误,请检查输入!\n");
}
} //打印帮助信息
void ContactHelp(Contact *p)
{
printf("*******************************************\n");
printf("****** add ---- 添加联系人信息 ******\n");
printf("****** del ---- 删除联系人信息 ******\n");
printf("****** search ---- 查找联系人信息 ******\n");
printf("****** modify ---- 修改联系人信息 ******\n");
printf("****** show ---- 展示联系人信息 ******\n");
printf("****** help ---- 帮助信息 ******\n");
printf("****** sort ---- 排序联系人信息 ******\n");
printf("****** exit ---- 退出通讯录 ******\n");
printf("*******************************************\n");
} //退出通讯录
void ContactExit(Contact *p)
{
printf("exit !\n");
}

Contact.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("****** 7.help 0.exit ******\n");
printf("******************************************\n");
} void test()
{
Contact list;//定义一个通讯录
Contact *p = &list;//赋址 //初始化
ContactInit(p);
int input = 0;//存放用户选择的信息
do
{
menu();
printf("请输入你的选择:>");
scanf("%d", &input);
switch (input)
{
case ADD:
ContactAdd(p);
break;
case DEL:
ContactDel(p);
break;
case SEARCH:
ContactSearch(p);
break;
case MODIFY:
ContactModify(p);
break;
case SHOW:
ContactShow(p);
break;
case SORT:
ContactSort(p);
break;
case HELP:
ContactHelp(p);
break;
case EXIT:
ContactExit(p);
break;
default:
printf("输入非法!\n");
}
} while (input); } void test2()
{
Contact list;//定义一个通讯录
Contact *p = &list;//赋址
//初始化
ContactInit(p);
//用一个函数指针数组来存放函数指针
void (*fun[])(Contact *) ={ContactExit,
ContactAdd,
ContactDel,
ContactSearch,
ContactModify,
ContactShow,
ContactSort,
ContactHelp};
int input = 0;//存放用户选择的信息
do{
menu();
printf("请输入你的选择:>");
scanf("%d", &input);
system("cls");
if(input>=0&&input<=sizeof(fun))
{
fun[input](p);
system("cls");
}
else
{
system("cls");
printf("输入非法,请检查输入!\n");
}
}while(input);
} int main()
{
//test();
test2(); return 0;
}

main.c

二.动态通讯录

  动态实现的问题主要在于它的容量不再是一变不变的,而是可随着我们的数据量来变化的,所以在我们原来定义的Contact结构体就要微微改变一下了:

typedef struct Contact
{
Data* data;//存放数据
int size;//有效数据的个数
int capacity;//容量的大小
} Contact;

  初始化函数也要改改:

//初始化 --- 动态
void ContactInit(Contact *p)
{
assert(p);
p->data=NULL;
p->size=0;
p->capacity=1;
}

  那么这样,添加函数也有一定的变化:

//检查容量函数
void CheckCapacity(Contact *p)
{
assert(p);
//如果联系人个数为0或与容量相同,就需要扩容
if (p->size == 0 || p->size == p->capacity)
{
//动态内存开辟
Data *ptr = (Data *) realloc(p->data, sizeof(Data) * p->capacity * 2);
if (ptr == NULL)//开辟失败
{
//报错
perror("CHECK CAPACITY ERROE !\n");
exit(-1);
}
//开辟成功,重新赋值
p->data = ptr;
//扩容之后,容量也相应扩大
p->capacity *= 2;
}
//反之什么都不需要干
} //添加联系人 --- 动态
void ContactAdd(Contact *p)
{
//断言保证p不为NULL
assert(p);
//如果联系人个数等于容量,或联系人个数等于0,这时我们就需要扩容了,我们来使用一个函数来干这事
CheckCapacity(p);
Data person;//记录联系人信息
printf("请输入联系人的姓名:>");
scanf("%s", person.name);
printf("请输入联系人的年龄:>");
scanf("%d", &person.age);
printf("请输入联系人的性别:>");
scanf("%s", person.sex);
printf("请输入联系人的电话:>");
scanf("%s", person.pnum);
printf("请输入联系人的住址:>");
scanf("%s", person.addr);
//将联系人信息存到通讯录中
p->data[p->size] = person;
p->size++;
}

  最后我们还要记得释放我们开辟的内存 --- 退出

//退出通讯录 --- 动态
void ContactExit(Contact *p)
{
//释放我们开辟的内存
free(p->data);
printf("exit !\n");
}

  动态通讯录的修改就只有这些:

  完整代码展示:

//确保文件只包含一次
#ifndef CONTACT_CONTACT_H
#define CONTACT_CONTACT_H #include <stdio.h>
#include <string.h>
#include <errno.h>
#include <stdlib.h>
#include <assert.h> //采用宏的目的是方便日后修改
#define NAME_MAX 20
#define SEX_MAX 8
#define PNUM_MAX 13
#define ADDR_MAX 20
#define MAX 10 //存放个人信息的结构体
typedef struct Data
{
char name[NAME_MAX];//姓名
int age;//年龄
char sex[SEX_MAX];//性别
char pnum[PNUM_MAX];//电话
char addr[ADDR_MAX];//地址
} Data; /*
//存放MAX个个人信息的通讯录 --- 静态
typedef struct Contact
{
Data data[MAX];
int size;
} Contact;
*/
//存放MAX个个人信息的通讯录 --- 动态
typedef struct Contact
{
Data* data;//存放数据
int size;//有效数据的个数
int capacity;//容量的大小
} Contact; //枚举来作为常量使得在看代码时比较清晰
enum choice
{
EXIT,
ADD,
DEL,
SEARCH,
MODIFY,
SHOW,
SORT,
HELP
}; enum sort_by
{
NAME=1,
SEX,
AGE,
PNUM,
ADDR
}; //初始化通讯录
void ContactInit(Contact *p); //添加联系人
void ContactAdd(Contact* p); //删除联系人
void ContactDel(Contact* p); //查找联系人
void ContactSearch(Contact* p); //修改联系人信息
void ContactModify(Contact* p); //展示联系人信息
void ContactShow(Contact* p); //排序联系人
void ContactSort(Contact* p); //打印帮助
void ContactHelp(Contact* p); //退出通讯录
void ContactExit(Contact* p); #endif //CONTACT_CONTACT_H

Contact.h

#include "Contact.h"
// 强调!!!
//调试请加setbuf(stdout,NULL)!!! //查找模块
int ContactFind(Contact *p, char *FindData)
{
assert(p);
int i = 0;
for (i = 0; i < p->size; i++)
{
if (strcmp(p->data[i].name, FindData) == 0)
{
return i;//找到就返回下标
}
}
return -1;//找不到就返回-1
} /*
//初始化 --- 静态
void ContactInit(Contact *p)
{
//保证p不为NULL
assert(p);
//置零
memset(p->data, 0, sizeof(p->data));
p->size = 0; }
*/ //初始化 --- 动态
void ContactInit(Contact *p)
{
assert(p);
p->data = NULL;
p->size = 0;
p->capacity = 1;
} /*//添加联系人 --- 静态
void ContactAdd(Contact *p)
{
//断言保证p不为NULL
assert(p);
//如果联系人容量已经等于最大容量了
if (p->size == MAX)
{
printf("通讯录已满,请删除一些后继续添加!\n");
return;
}
Data person;//记录联系人信息
printf("请输入联系人的姓名:>");
scanf("%s", person.name);
printf("请输入联系人的年龄:>");
scanf("%d", &person.age);
printf("请输入联系人的性别:>");
scanf("%s", person.sex);
printf("请输入联系人的电话:>");
scanf("%s", person.pnum);
printf("请输入联系人的住址:>");
scanf("%s", person.addr);
//将联系人信息存到通讯录中
p->data[p->size] = person;
p->size++;
}*/ //检查容量函数
void CheckCapacity(Contact *p)
{
assert(p);
//如果联系人个数为0或与容量相同,就需要扩容
if (p->size == 0 || p->size == p->capacity)
{
//动态内存开辟
Data *ptr = (Data *) realloc(p->data, sizeof(Data) * p->capacity * 2);
if (ptr == NULL)//开辟失败
{
//报错
perror("CHECK CAPACITY ERROE !\n");
exit(-1);
}
//开辟成功,重新赋值
p->data = ptr;
//扩容之后,容量也相应扩大
p->capacity *= 2;
}
//反之什么都不需要干
} //添加联系人 --- 动态
void ContactAdd(Contact *p)
{
//断言保证p不为NULL
assert(p);
//如果联系人个数等于容量,或联系人个数等于0,这时我们就需要扩容了,我们来使用一个函数来干这事
CheckCapacity(p);
Data person;//记录联系人信息
printf("请输入联系人的姓名:>");
scanf("%s", person.name);
printf("请输入联系人的年龄:>");
scanf("%d", &person.age);
printf("请输入联系人的性别:>");
scanf("%s", person.sex);
printf("请输入联系人的电话:>");
scanf("%s", person.pnum);
printf("请输入联系人的住址:>");
scanf("%s", person.addr);
//将联系人信息存到通讯录中
p->data[p->size] = person;
p->size++;
} //删除联系人
void ContactDel(Contact *p)
{
assert(p);
char DelName[NAME_MAX] = {0};
printf("请输入你要删除的联系人姓名:>");
scanf("%s", DelName);
int ret = ContactFind(p, DelName);
if (ret == -1)
{
printf("通讯录中并无此人,请重新检查输入!\n");
} else
{
int j = 0;
for (j = ret; j < p->size; j++)
{
//从前往后依次挪动覆盖
p->data[j] = p->data[j + 1];
}
//删除完成之后,联系人个数减一
p->size--;
}
} //查找联系人
void ContactSearch(Contact *p)
{
assert(p);
char SearchName[NAME_MAX];
printf("请输入你要查找的联系人姓名:>");
scanf("%s", SearchName);
//查找有无此人
int ret = ContactFind(p, SearchName);
if (ret == -1)
{
printf("通讯录中并无此人,请重新检查输入!\n");
} else
{
printf("你所查找的联系人信息为:\n");
printf(" 姓名\t性别\t 年龄\t 电话\t\t地址\n");
printf(" %-5s\t%s\t%d\t%s\t%s\n", p->data[ret].name,
p->data[ret].sex,
p->data[ret].age,
p->data[ret].pnum,
p->data[ret].addr);
}
} //修改联系人信息
void ContactModify(Contact *p)
{
assert(p);
char ModifyName[NAME_MAX];
printf("请输入你要修改的联系人姓名:>");
scanf("%s", ModifyName);
int ret = ContactFind(p, ModifyName);
if (ret == -1)
{
printf("通讯录中并无此人,请重新检查输入!\n");
} else
{
Data person;//记录联系人信息
printf("请输入联系人的姓名:>");
scanf("%s", person.name);
printf("请输入联系人的年龄:>");
scanf("%d", &person.age);
printf("请输入联系人的性别:>");
scanf("%s", person.sex);
printf("请输入联系人的电话:>");
scanf("%s", person.pnum);
printf("请输入联系人的住址:>");
scanf("%s", person.addr);
//将联系人信息存到通讯录中
p->data[ret] = person;
}
} //展示联系人信息
void ContactShow(Contact *p)
{
if (p->size == 0)
{
printf("通讯录中并无一人!\n");
return;
} int i = 0;
printf(" 姓名\t性别\t 年龄\t 电话\t\t地址\n");
for (i = 0; i < p->size; i++)
{
printf(" %-5s\t%s\t%d\t%s\t%s\n", p->data[i].name,
p->data[i].sex,
p->data[i].age,
p->data[i].pnum,
p->data[i].addr); }
} void sort_menu()
{
printf(" SORT_MENU \n");
printf("******************************\n");
printf("**** 1.name ****\n");
printf("**** 2.sex ****\n");
printf("**** 3.age ****\n");
printf("**** 4.pnum ****\n");
printf("**** 5.addr ****\n");
printf("******************************\n");
} int sort_by_name(const void *s1, const void *s2)
{
return strcmp(((Data *) s1)->name, ((Data *) s2)->name);
} int sort_by_sex(const void *s1, const void *s2)
{
return strcmp(((Data *) s1)->sex, ((Data *) s2)->sex);
} int sort_by_age(const void *s1, const void *s2)
{
return ((Data *) s1)->age - ((Data *) s2)->age;
} int sort_by_pnum(const void *s1, const void *s2)
{
return strcmp(((Data *) s1)->pnum, ((Data *) s2)->pnum);
} int sort_by_addr(const void *s1, const void *s2)
{
return strcmp(((Data *) s1)->addr, ((Data *) s2)->addr);
} //排序联系人
void ContactSort(Contact *p)
{
assert(p);
int choice;
sort_menu();
printf("请选择排序的参考量:>");
scanf("%d", &choice);
switch (choice)
{
case NAME:
qsort(p->data, p->size, sizeof(Data), sort_by_name);
break;
case SEX:
qsort(p->data, p->size, sizeof(Data), sort_by_sex);
break;
case AGE:
qsort(p->data, p->size, sizeof(Data), sort_by_age);
break;
case PNUM:
qsort(p->data, p->size, sizeof(Data), sort_by_pnum);
break;
case ADDR:
qsort(p->data, p->size, sizeof(Data), sort_by_addr);
break;
default:
printf("输入有误,请检查输入!\n");
}
} //打印帮助信息
void ContactHelp(Contact *p)
{
printf("*******************************************\n");
printf("****** add ---- 添加联系人信息 ******\n");
printf("****** del ---- 删除联系人信息 ******\n");
printf("****** search ---- 查找联系人信息 ******\n");
printf("****** modify ---- 修改联系人信息 ******\n");
printf("****** show ---- 展示联系人信息 ******\n");
printf("****** help ---- 帮助信息 ******\n");
printf("****** sort ---- 排序联系人信息 ******\n");
printf("****** exit ---- 退出通讯录 ******\n");
printf("*******************************************\n");
} /*//退出通讯录
void ContactExit(Contact *p)
{
printf("exit !\n");
}*/ //退出通讯录 --- 动态
void ContactExit(Contact *p)
{
//释放我们开辟的内存
free(p->data);
printf("exit !\n");
}

Contact.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("****** 7.help 0.exit ******\n");
printf("******************************************\n");
} void test()
{
Contact list;//定义一个通讯录
Contact *p = &list;//赋址 //初始化
ContactInit(p);
int input = 0;//存放用户选择的信息
do
{
menu();
printf("请输入你的选择:>");
scanf("%d", &input);
switch (input)
{
case ADD:
ContactAdd(p);
break;
case DEL:
ContactDel(p);
break;
case SEARCH:
ContactSearch(p);
break;
case MODIFY:
ContactModify(p);
break;
case SHOW:
ContactShow(p);
break;
case SORT:
ContactSort(p);
break;
case HELP:
ContactHelp(p);
break;
case EXIT:
ContactExit(p);
break;
default:
printf("输入非法!\n");
}
} while (input); } void test2()
{
Contact list;//定义一个通讯录
Contact *p = &list;//赋址
//初始化
ContactInit(p);
//用一个函数指针数组来存放函数指针
void (*fun[])(Contact *) ={ContactExit,
ContactAdd,
ContactDel,
ContactSearch,
ContactModify,
ContactShow,
ContactSort,
ContactHelp};
int input = 0;//存放用户选择的信息
do{
menu();
printf("请输入你的选择:>");
scanf("%d", &input);
if(input>=0&&input<=sizeof(fun))
{
//system("cls");
fun[input](p); }
else
{
system("cls");
printf("输入非法,请检查输入!\n");
}
}while(input);
} int main()
{
//test();
test2(); return 0;
} #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("****** 7.help 0.exit ******\n");
printf("******************************************\n");
} void test()
{
Contact list;//定义一个通讯录
Contact *p = &list;//赋址 //初始化
ContactInit(p);
int input = 0;//存放用户选择的信息
do
{
menu();
printf("请输入你的选择:>");
scanf("%d", &input);
switch (input)
{
case ADD:
ContactAdd(p);
break;
case DEL:
ContactDel(p);
break;
case SEARCH:
ContactSearch(p);
break;
case MODIFY:
ContactModify(p);
break;
case SHOW:
ContactShow(p);
break;
case SORT:
ContactSort(p);
break;
case HELP:
ContactHelp(p);
break;
case EXIT:
ContactExit(p);
break;
default:
printf("输入非法!\n");
}
} while (input); } void test2()
{
Contact list;//定义一个通讯录
Contact *p = &list;//赋址
//初始化
ContactInit(p);
//用一个函数指针数组来存放函数指针
void (*fun[])(Contact *) ={ContactExit,
ContactAdd,
ContactDel,
ContactSearch,
ContactModify,
ContactShow,
ContactSort,
ContactHelp};
int input = 0;//存放用户选择的信息
do{
menu();
printf("请输入你的选择:>");
scanf("%d", &input);
if(input>=0&&input<=sizeof(fun))
{
//system("cls");
fun[input](p); }
else
{
system("cls");
printf("输入非法,请检查输入!\n");
}
}while(input);
} int main()
{
//test();
test2(); return 0;
}

main.c

三.带文件的动态通讯录

  在这个里面,我们只需在初始化时进行文件的读取及关闭时文件的保存:

  初始化:

//从文件载入信息
void Lodging(Contact *p)
{
assert(p);
//打开一文件
FILE *fp = fopen("../Contact.dat", "ab");//如果不存在就创建,存在就追加
if (fp == NULL)
{
perror("FILE: Ab");
exit(-1);
}
fclose(fp);//关闭文件,我们这一步只是为了确保文件存在
//打开一文件
fp=fopen("../Contact.dat","rb");
if (fp == NULL)
{
perror("FILE: Rb");
exit(-1);
}
Data temp;//将读入的信息存入temp中
while(fread(&temp, sizeof(Data),1,fp))
{
//检查容量
CheckCapacity(p);
//赋值
p->data[p->size]=temp;
p->size++;
}
fclose(fp);//关闭文件
} //初始化 --- 带文件
void ContactInit(Contact *p)
{
assert(p);
p->data = NULL;
p->size = 0;
p->capacity = 1;
Lodging(p);
}

  结束时保存:

void Save(Contact* p)
{
assert(p);
FILE* fp =fopen("../Contact.dat","wb");
int i =0;
for(i=0;i<p->size;i++)
{
fwrite(p->data+i, sizeof(Data),1,fp);
}
fclose(fp);
} //退出通讯录 --- 带文件
void ContactExit(Contact *p)
{
//保存置文件
Save(p);
//释放我们开辟的内存
free(p->data);
printf("exit !\n");
}

  除此之外,其他都与动态通讯录相同

  完整代码:

//确保文件只包含一次
#ifndef CONTACT_CONTACT_H
#define CONTACT_CONTACT_H #include <stdio.h>
#include <string.h>
#include <errno.h>
#include <stdlib.h>
#include <assert.h> //采用宏的目的是方便日后修改
#define NAME_MAX 20
#define SEX_MAX 8
#define PNUM_MAX 13
#define ADDR_MAX 20
#define MAX 10 //存放个人信息的结构体
typedef struct Data
{
char name[NAME_MAX];//姓名
int age;//年龄
char sex[SEX_MAX];//性别
char pnum[PNUM_MAX];//电话
char addr[ADDR_MAX];//地址
} Data; /*
//存放MAX个个人信息的通讯录 --- 静态
typedef struct Contact
{
Data data[MAX];
int size;
} Contact;
*/
//存放MAX个个人信息的通讯录 --- 动态
typedef struct Contact
{
Data* data;//存放数据
int size;//有效数据的个数
int capacity;//容量的大小
} Contact; //枚举来作为常量使得在看代码时比较清晰
enum choice
{
EXIT,
ADD,
DEL,
SEARCH,
MODIFY,
SHOW,
SORT,
HELP
}; enum sort_by
{
NAME=1,
SEX,
AGE,
PNUM,
ADDR
}; //初始化通讯录
void ContactInit(Contact *p); //添加联系人
void ContactAdd(Contact* p); //删除联系人
void ContactDel(Contact* p); //查找联系人
void ContactSearch(Contact* p); //修改联系人信息
void ContactModify(Contact* p); //展示联系人信息
void ContactShow(Contact* p); //排序联系人
void ContactSort(Contact* p); //打印帮助
void ContactHelp(Contact* p); //退出通讯录
void ContactExit(Contact* p); //检查容量函数
void CheckCapacity(Contact *p); #endif //CONTACT_CONTACT_H

Contact.h

#include "Contact.h"
// 强调!!!
//调试请加setbuf(stdout,NULL)!!! //查找模块
int ContactFind(Contact *p, char *FindData)
{
assert(p);
int i = 0;
for (i = 0; i < p->size; i++)
{
if (strcmp(p->data[i].name, FindData) == 0)
{
return i;//找到就返回下标
}
}
return -1;//找不到就返回-1
} /*
//初始化 --- 静态
void ContactInit(Contact *p)
{
//保证p不为NULL
assert(p);
//置零
memset(p->data, 0, sizeof(p->data));
p->size = 0; }
*/ /*
//初始化 --- 动态
void ContactInit(Contact *p)
{
assert(p);
p->data = NULL;
p->size = 0;
p->capacity = 1;
}
*/ //从文件载入信息
void Lodging(Contact *p)
{
assert(p);
//打开一文件
FILE *fp = fopen("../Contact.dat", "ab");//如果不存在就创建,存在就追加
if (fp == NULL)
{
perror("FILE: Ab");
exit(-1);
}
fclose(fp);//关闭文件,我们这一步只是为了确保文件存在
//打开一文件
fp=fopen("../Contact.dat","rb");
if (fp == NULL)
{
perror("FILE: Rb");
exit(-1);
}
Data temp;//将读入的信息存入temp中
while(fread(&temp, sizeof(Data),1,fp))
{
//检查容量
CheckCapacity(p);
//赋值
p->data[p->size]=temp;
p->size++;
}
fclose(fp);//关闭文件
} //初始化 --- 带文件
void ContactInit(Contact *p)
{
assert(p);
p->data = NULL;
p->size = 0;
p->capacity = 1;
Lodging(p);
} /*//添加联系人 --- 静态
void ContactAdd(Contact *p)
{
//断言保证p不为NULL
assert(p);
//如果联系人容量已经等于最大容量了
if (p->size == MAX)
{
printf("通讯录已满,请删除一些后继续添加!\n");
return;
}
Data person;//记录联系人信息
printf("请输入联系人的姓名:>");
scanf("%s", person.name);
printf("请输入联系人的年龄:>");
scanf("%d", &person.age);
printf("请输入联系人的性别:>");
scanf("%s", person.sex);
printf("请输入联系人的电话:>");
scanf("%s", person.pnum);
printf("请输入联系人的住址:>");
scanf("%s", person.addr);
//将联系人信息存到通讯录中
p->data[p->size] = person;
p->size++;
}*/ //检查容量函数
void CheckCapacity(Contact *p)
{
assert(p);
//如果联系人个数为0或与容量相同,就需要扩容
if (p->size == 0 || p->size == p->capacity)
{
//动态内存开辟
Data *ptr = (Data *) realloc(p->data, sizeof(Data) * p->capacity * 2);
if (ptr == NULL)//开辟失败
{
//报错
perror("CHECK CAPACITY ERROE !\n");
exit(-1);
}
//开辟成功,重新赋值
p->data = ptr;
//扩容之后,容量也相应扩大
p->capacity *= 2;
}
//反之什么都不需要干
} //添加联系人 --- 动态
void ContactAdd(Contact *p)
{
//断言保证p不为NULL
assert(p);
//如果联系人个数等于容量,或联系人个数等于0,这时我们就需要扩容了,我们来使用一个函数来干这事
CheckCapacity(p);
Data person;//记录联系人信息
printf("请输入联系人的姓名:>");
scanf("%s", person.name);
printf("请输入联系人的年龄:>");
scanf("%d", &person.age);
printf("请输入联系人的性别:>");
scanf("%s", person.sex);
printf("请输入联系人的电话:>");
scanf("%s", person.pnum);
printf("请输入联系人的住址:>");
scanf("%s", person.addr);
//将联系人信息存到通讯录中
p->data[p->size] = person;
p->size++;
} //删除联系人
void ContactDel(Contact *p)
{
assert(p);
char DelName[NAME_MAX] = {0};
printf("请输入你要删除的联系人姓名:>");
scanf("%s", DelName);
int ret = ContactFind(p, DelName);
if (ret == -1)
{
printf("通讯录中并无此人,请重新检查输入!\n");
} else
{
int j = 0;
for (j = ret; j < p->size; j++)
{
//从前往后依次挪动覆盖
p->data[j] = p->data[j + 1];
}
//删除完成之后,联系人个数减一
p->size--;
}
} //查找联系人
void ContactSearch(Contact *p)
{
assert(p);
char SearchName[NAME_MAX];
printf("请输入你要查找的联系人姓名:>");
scanf("%s", SearchName);
//查找有无此人
int ret = ContactFind(p, SearchName);
if (ret == -1)
{
printf("通讯录中并无此人,请重新检查输入!\n");
} else
{
printf("你所查找的联系人信息为:\n");
printf(" 姓名\t性别\t 年龄\t 电话\t\t地址\n");
printf(" %-5s\t%s\t%d\t%s\t%s\n", p->data[ret].name,
p->data[ret].sex,
p->data[ret].age,
p->data[ret].pnum,
p->data[ret].addr);
}
} //修改联系人信息
void ContactModify(Contact *p)
{
assert(p);
char ModifyName[NAME_MAX];
printf("请输入你要修改的联系人姓名:>");
scanf("%s", ModifyName);
int ret = ContactFind(p, ModifyName);
if (ret == -1)
{
printf("通讯录中并无此人,请重新检查输入!\n");
} else
{
Data person;//记录联系人信息
printf("请输入联系人的姓名:>");
scanf("%s", person.name);
printf("请输入联系人的年龄:>");
scanf("%d", &person.age);
printf("请输入联系人的性别:>");
scanf("%s", person.sex);
printf("请输入联系人的电话:>");
scanf("%s", person.pnum);
printf("请输入联系人的住址:>");
scanf("%s", person.addr);
//将联系人信息存到通讯录中
p->data[ret] = person;
}
} //展示联系人信息
void ContactShow(Contact *p)
{
assert(p);
if (p->size == 0)
{
printf("通讯录中并无一人!\n");
return;
} int i = 0;
printf(" 姓名\t性别\t 年龄\t 电话\t\t地址\n");
for (i = 0; i < p->size; i++)
{
printf(" %-5s\t%s\t%d\t%s\t%s\n", p->data[i].name,
p->data[i].sex,
p->data[i].age,
p->data[i].pnum,
p->data[i].addr); }
} void sort_menu()
{
printf(" SORT_MENU \n");
printf("******************************\n");
printf("**** 1.name ****\n");
printf("**** 2.sex ****\n");
printf("**** 3.age ****\n");
printf("**** 4.pnum ****\n");
printf("**** 5.addr ****\n");
printf("******************************\n");
} int sort_by_name(const void *s1, const void *s2)
{
return strcmp(((Data *) s1)->name, ((Data *) s2)->name);
} int sort_by_sex(const void *s1, const void *s2)
{
return strcmp(((Data *) s1)->sex, ((Data *) s2)->sex);
} int sort_by_age(const void *s1, const void *s2)
{
return ((Data *) s1)->age - ((Data *) s2)->age;
} int sort_by_pnum(const void *s1, const void *s2)
{
return strcmp(((Data *) s1)->pnum, ((Data *) s2)->pnum);
} int sort_by_addr(const void *s1, const void *s2)
{
return strcmp(((Data *) s1)->addr, ((Data *) s2)->addr);
} //排序联系人
void ContactSort(Contact *p)
{
assert(p);
int choice;
sort_menu();
printf("请选择排序的参考量:>");
scanf("%d", &choice);
switch (choice)
{
case NAME:
qsort(p->data, p->size, sizeof(Data), sort_by_name);
break;
case SEX:
qsort(p->data, p->size, sizeof(Data), sort_by_sex);
break;
case AGE:
qsort(p->data, p->size, sizeof(Data), sort_by_age);
break;
case PNUM:
qsort(p->data, p->size, sizeof(Data), sort_by_pnum);
break;
case ADDR:
qsort(p->data, p->size, sizeof(Data), sort_by_addr);
break;
default:
printf("输入有误,请检查输入!\n");
}
} //打印帮助信息
void ContactHelp(Contact *p)
{
printf("*******************************************\n");
printf("****** add ---- 添加联系人信息 ******\n");
printf("****** del ---- 删除联系人信息 ******\n");
printf("****** search ---- 查找联系人信息 ******\n");
printf("****** modify ---- 修改联系人信息 ******\n");
printf("****** show ---- 展示联系人信息 ******\n");
printf("****** help ---- 帮助信息 ******\n");
printf("****** sort ---- 排序联系人信息 ******\n");
printf("****** exit ---- 退出通讯录 ******\n");
printf("*******************************************\n");
} /*//退出通讯录
void ContactExit(Contact *p)
{
printf("exit !\n");
}*/ /*
//退出通讯录 --- 动态
void ContactExit(Contact *p)
{
//释放我们开辟的内存
free(p->data);
printf("exit !\n");
}*/ void Save(Contact* p)
{
assert(p);
FILE* fp =fopen("../Contact.dat","wb");
int i =0;
for(i=0;i<p->size;i++)
{
fwrite(p->data+i, sizeof(Data),1,fp);
}
fclose(fp);
} //退出通讯录 --- 带文件
void ContactExit(Contact *p)
{
//保存置文件
Save(p);
//释放我们开辟的内存
free(p->data);
printf("exit !\n");
}

Contact.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("****** 7.help 0.exit ******\n");
printf("******************************************\n");
} void test()
{
Contact list;//定义一个通讯录
Contact *p = &list;//赋址 //初始化
ContactInit(p);
int input = 0;//存放用户选择的信息
do
{
menu();
printf("请输入你的选择:>");
scanf("%d", &input);
switch (input)
{
case ADD:
ContactAdd(p);
break;
case DEL:
ContactDel(p);
break;
case SEARCH:
ContactSearch(p);
break;
case MODIFY:
ContactModify(p);
break;
case SHOW:
ContactShow(p);
break;
case SORT:
ContactSort(p);
break;
case HELP:
ContactHelp(p);
break;
case EXIT:
ContactExit(p);
break;
default:
printf("输入非法!\n");
}
} while (input); } void test2()
{
Contact list;//定义一个通讯录
Contact *p = &list;//赋址
//初始化
ContactInit(p);
//用一个函数指针数组来存放函数指针
void (*fun[])(Contact *) ={ContactExit,
ContactAdd,
ContactDel,
ContactSearch,
ContactModify,
ContactShow,
ContactSort,
ContactHelp};
int input = 0;//存放用户选择的信息
do{
menu();
printf("请输入你的选择:>");
scanf("%d", &input);
if(input>=0&&input<=sizeof(fun))
{
//system("cls");
fun[input](p); }
else
{
system("cls");
printf("输入非法,请检查输入!\n");
}
}while(input);
} int main()
{
//test();
test2(); return 0;
}

main.c


|---------------------------------------------------------------------------------------------------

到此,我们的C语言也就告一段落了!

以后的路我们依然任重而道远!

C语言之通讯录的模拟实现的更多相关文章

  1. C语言之库函数的模拟与使用

    C语言之库函数的模拟与使用 在我们学习C语言的过程中,难免会遇到这样的一种情况: 我们通常实现一个功能的时候,费尽心血的写出来,却有着满满的错,这时却有人来告诉你说:这个功能可以用相应的库函数来实现. ...

  2. 大二作业——操作系统实验——C语言用双向链表,模拟实现动态分区式存储管理

    实验:动态分区式存储管理 实验内容: 编写程序模拟完成动态分区存储管理方式的内存分配和回收.实验具体包括:首先确定内存空闲分配表:然后采用最佳适应算法完成内存空间的分配和回收:最后编写主函数对所做工作 ...

  3. c语言实现通讯录管理系统(c课程设计)

    工具:Visual C++6.0 说明: 本系统基于C语言实现班级通讯录管理系统,为大一时学习C语言刚入门所做的课程设计.功能包括增.删.查.改等,非常适合初学者练手.通讯录包括的个人信息有姓名.学号 ...

  4. C语言-《通讯录》

    黑白的通讯录 --1-- 需求分析 1.1 需求 1.2 原型展示 1.3 功能分析 --2-- 代码实现 2.1 外部声明.变量.宏 2.2 模块实现 ----------------------- ...

  5. Iphone 英语语言下通讯录排序问题

    Iphone 如果把界面语言设置成English,那么通讯录默认排序是通过拼音来排的,如果联系人信息中没有设置名字的拼音,那么这些联系人都会被放到#中. 批量添加拼音的解决方案: https://gi ...

  6. 基于visual Studio2013解决C语言竞赛题之1088模拟计算器

        题目 解决代码及点评 /************************************************************************/ /* ...

  7. C语言实现通讯录

    <span style="font-size:18px;">#include<stdio.h> #include<string.h> #incl ...

  8. 2、C语言实现通讯录

    main函数入口: //test.c #include<stdio.h> #include<stdlib.h> #include<string.h> #includ ...

  9. C语言:读TXT 模拟键盘打字输出

    //#include<ctype.h> #include<stdio.h> #include <windows.h> //#include "string ...

随机推荐

  1. React Hooks: useRef All In One

    React Hooks: useRef All In One useRef https://reactjs.org/docs/hooks-reference.html#useref refs xgqf ...

  2. GitHub & GraphQL API

    GitHub & GraphQL API https://gist.github.com/xgqfrms/15559e7545f558d85c5efdea79171a3d refs xgqfr ...

  3. OLAP

    OLAP Online Analytical Processing https://en.wikipedia.org/wiki/Online_analytical_processing 在线分析处理 ...

  4. modal 遮罩层,滚动穿透 bug

    modal 遮罩层,滚动 穿透bug float 弹层 taro 小程序弹框 滚动击穿 问题 https://segmentfault.com/q/1010000011134345 solution ...

  5. TypeScript & Advanced Types

    TypeScript & Advanced Types https://www.typescriptlang.org/docs/handbook/advanced-types.html#typ ...

  6. NGK发力社区 打造三大社群模式

    当人们谈论区块链.数字货币的时候,常常会提到这样一些词汇:社区.社群,社区对区块链项目乃至于整个区块链行业的重要性已经形成了基本的行业共识,几乎每个项目方都在想尽办法营造社区.激发社区活力. 为什么区 ...

  7. K8S部署Redis Cluster集群

    kubernetes部署单节点redis: https://www.cnblogs.com/zisefeizhu/p/14282299.html Redis 介绍 • Redis代表REmote DI ...

  8. Vue学习笔记-Vue.js-2.X 学习(五)===>脚手架Vue-CLI(PyCharm)

    Vue项目在pycharm中配置 退出运行: ctrl+c Vue学习笔记-Vue.js-2.X 学习(六)===>脚手架Vue-CLI(项目说明)

  9. 使用 Tye 辅助开发 k8s 应用竟如此简单(六)

    续上篇,这篇我们来进一步探索 Tye 更多的使用方法.本篇我们将进一步研究 Tye 与分布式应用程序运行时 Dapr 如何碰撞出更精彩的火花. Newbe.Claptrap 是一个用于轻松应对并发问题 ...

  10. Android7.0无需FileProvide搞定URI拍照、应用安装问题

    根据官方文档,从Android7.0版本开始 使用URI打开或安装文件需要单独在应用里配置了,问了度娘,有好多版本的结果,个人认为最靠谱的就是下边这个方法,只需在application的oncreat ...