C语言之通讯录的模拟实现
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语言之通讯录的模拟实现的更多相关文章
- C语言之库函数的模拟与使用
C语言之库函数的模拟与使用 在我们学习C语言的过程中,难免会遇到这样的一种情况: 我们通常实现一个功能的时候,费尽心血的写出来,却有着满满的错,这时却有人来告诉你说:这个功能可以用相应的库函数来实现. ...
- 大二作业——操作系统实验——C语言用双向链表,模拟实现动态分区式存储管理
实验:动态分区式存储管理 实验内容: 编写程序模拟完成动态分区存储管理方式的内存分配和回收.实验具体包括:首先确定内存空闲分配表:然后采用最佳适应算法完成内存空间的分配和回收:最后编写主函数对所做工作 ...
- c语言实现通讯录管理系统(c课程设计)
工具:Visual C++6.0 说明: 本系统基于C语言实现班级通讯录管理系统,为大一时学习C语言刚入门所做的课程设计.功能包括增.删.查.改等,非常适合初学者练手.通讯录包括的个人信息有姓名.学号 ...
- C语言-《通讯录》
黑白的通讯录 --1-- 需求分析 1.1 需求 1.2 原型展示 1.3 功能分析 --2-- 代码实现 2.1 外部声明.变量.宏 2.2 模块实现 ----------------------- ...
- Iphone 英语语言下通讯录排序问题
Iphone 如果把界面语言设置成English,那么通讯录默认排序是通过拼音来排的,如果联系人信息中没有设置名字的拼音,那么这些联系人都会被放到#中. 批量添加拼音的解决方案: https://gi ...
- 基于visual Studio2013解决C语言竞赛题之1088模拟计算器
题目 解决代码及点评 /************************************************************************/ /* ...
- C语言实现通讯录
<span style="font-size:18px;">#include<stdio.h> #include<string.h> #incl ...
- 2、C语言实现通讯录
main函数入口: //test.c #include<stdio.h> #include<stdlib.h> #include<string.h> #includ ...
- C语言:读TXT 模拟键盘打字输出
//#include<ctype.h> #include<stdio.h> #include <windows.h> //#include "string ...
随机推荐
- JSON-LD 结构化数据
JSON-LD 结构化数据 SEO JSON-LD JSON for Linking Data JSON 链接数据 https://json-ld.org/ https://en.wikipedia. ...
- koa url path & koa-router
koa url path & koa-router url path & regex koa path router "use strict"; /** * * @ ...
- npm init & npx create & yarn create
npm init & npx create & yarn create https://create-react-app.dev/docs/getting-started/#creat ...
- DOM事件对象用法
分为三个阶段:事件捕获阶段.目标阶段.事件冒泡阶段. 事件捕获老版本浏览器(IE<=8)不支持,但是事件冒泡可以放心使用. 事件处理程序 一共四类写法,基本都见过,看下写法就知道怎么回事儿了. ...
- 「NGK每日快讯」12.29日NGK第56期官方快讯!
- C#使用OpenCV剪切图形中的人物头像
前言 本文主要介绍如何使用OpenCV剪切图形中的人物头像. 准备工作 首先创建一个Wpf项目--OpenCV_Face_Wpf,这里版本使用Framework4.7.2. 然后使用Nuget搜索[E ...
- Spark集成
一.Spark 架构与优化器 1.Spark架构 (重点) 2.Spark优化器 二.Spark+SQL的API (重点) 1.DataSet简介 2.DataFrame简介 3.RDD与DF/DS的 ...
- 6. vue组件详解(一)
主要内容: 1. 组件的基本使用 2. 全局组件和局部组件 3. 父组件和子组件 4. 组件语法糖的写法 5. 组件data关联的写法 6. 父子组件的通信 组件系统是 Vue 的一个重要概念,因为它 ...
- dategrip的使用技巧
原文链接:https://blog.csdn.net/weixin_44421461/article/details/109541903 数据表复制,可以直接用sql语句 1.复制表结构及数据到新表 ...
- HashMap什么时候进行扩容?
Threshold:table数组元素个数size的大小超过threshold且且Node<K,V>[] table数组长度没有超过64时时table数组扩容.当hashmap中的元素个数 ...