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. Swift 5.3 All In One

    Swift 5.3 All In One refs xgqfrms 2012-2020 www.cnblogs.com 发布文章使用:只允许注册用户才可以访问!

  2. node os env reader

    node os env reader node-os-env-reader.js #!/usr/bin/env node "use strict"; /** * * @author ...

  3. Cocos Creator 游戏开发

    Cocos Creator 游戏开发 https://www.cocos.com/products#CocosCreator 一体化编辑器: 包含了一体化.可扩展的编辑器,简化了资源管理.游戏调试和预 ...

  4. App Store Previewer

    App Store Previewer App Store 模拟器 https://www.storepreviewer.com/ xgqfrms 2012-2020 www.cnblogs.com ...

  5. 新兴公链NGK Global如何借助Defi突围?

    Defi正在掀起持续不减的热度,在过去的一段时间里,以Uniswap为代表的去中心化交易所,使得以太坊重新焕发生机.币价也较以往上涨了50%有余.而且这波热度同样波及到交易所和其他公链市场. 但是波及 ...

  6. 无法将“node.exe”项识别为 cmdlet、函数、脚本文件或可运行程序的名称

    有些天没有启动前端项目,发现npm run dev,启动不了,经过一番查找发现问题所在 然后我查看了一下报错位置,发现并没有改动过什么 解决方法: 方法一: 检查一下npm目录: 这里发现少了node ...

  7. Vuex入门、同步异步存取值进阶版

    关注公众号查看原文: 1. vueX介&绍安装 Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式.它采用集中式存储管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方 ...

  8. 《Asp.Net Core3 + Vue3入坑教程》-Net Core项目搭建与Swagger配置步骤

    简介 <Asp.Net Core3 + Vue3入坑教程> 此教程仅适合新手入门或者前后端分离尝试者.可以根据图文一步一步进操作编码也可以选择直接查看源码.每一篇文章都有对应的源码 教程后 ...

  9. .Net -- NLog日志框架配置与使用

    NLog是适用于各种.NET平台(包括.NET标准)的灵活,免费的日志记录平台,NLog可将日志写入多个目标,比如Database.File.Console.Mail.下面介绍下NLog的基本使用方法 ...

  10. Go语言实现布谷鸟过滤器

    转载请声明出处哦~,本篇文章发布于luozhiyun的博客:https://www.luozhiyun.com/archives/453 介绍 在我们工作中,如果遇到如网页 URL 去重.垃圾邮件识别 ...