该通讯录采用文件存储方式保存联系人信息,主要功能有增加联系人、删除联系人、查找联系人、修改联系人信息、显示五大功能,外加排序、保存两大副功能!
创建txl.h放头文件等需共用的代码,创建txlhs.c放所需的函数代码,创建txl.c进行测试
本程序未解决:联系人姓名重复问题与联系人信息重复问题
#include
#include
#include
#define MAX_NAME 20
#define MAX_TELE 12
#define MAX_ADDR 30
#define CP_SZ 5//通讯录开始容量为5
只需存放姓名、电话、住址即可,若要存其他可增加!
typedef struct Info {
char name[MAX_NAME];//姓名
char tele[MAX_TELE];//电话
char addr[MAX_ADDR];//住址
}Info;
typedef struct Contact {
Info* data;//存放信息
int size;//记录当前已有的通讯录人数
int capacity;//记录当前通讯录的容量
}Contact;
利用枚举功能,创建通讯录内部选择键,方便程序员写代码!
enum Option {
Exit,
Add,
Del,
Search,
Modify,
Show,
Sort
};
实现功能:增、删、改、查、显示、销毁、初始化!
void InitContact(Contact* p);//初始化通讯录
void AddContact(Contact* p);//添加联系人
void DelContact(Contact* p);//删除指定联系人
void SearchContact(const Contact* p);//查找联系人
void ModifyContact(Contact* p);//修改联系人信息
void ShowContact(Contact* p);//显示通讯录信息
void DestroyContact(Contact* p);//销毁通讯录
void slect();//主菜单选择函数
通讯录创建后我们得初始化通讯录:开辟动态存储空间、将通讯录已有人数设置为0,、容量初始化为5个(可在头文件中更改),并调用加载本地数据函数LoadContact(),加载本地数据到通讯录中!
void InitContact(Contact* p) {
p->data = (Info*)malloc(CP_SZ * sizeof(Info));
if (p->data == NULL) {
perror("InitContact"); system("pause"); return;
}
p->size = 0;
p->capacity = CP_SZ;
LoadContact(p);
}
将本地文件中的数据添加到通讯录中,添加之前调用容量检查函数CheckCapacity(),检查容量是否足够,若不够需增容,再写入!
void LoadContact(Contact *p) {
Info temp = { 0 };
FILE* fpRead = fopen("contact.dat", "rb");
if (fpRead == NULL) {
puts("加载数据失败!");
perror("contact.dat"); system("pause"); return;
}
while (fread(&temp, sizeof(Info), 1, fpRead)) {
CheckCapacity(p);
p->data[p->size] = temp;
p->size++;
}
fclose(fpRead);
fpRead = NULL;
}
检查通讯录中已有人数size与容量capacity是否相等;若相等,则需开辟空间(本人选择每次开辟5个),若不等,则什么也不做!
void CheckCapacity(Contact* p) {
if (p->size == p->capacity) {
Info* ptr = (Info*)realloc(p->data, (p->capacity + 5) * sizeof(Info));
if (ptr != NULL) {
p->data = ptr;
p->capacity += 2; puts("增容成功!");
}
else {
puts("增容失败!"); system("pause"); return;
}
}
}
添加前调用容量检查函数CheckCapacity(),检查通讯录的容量是否满足,再输入联系人信息,并将size增1(很重要)!
void AddContact(Contact* p) {
CheckCapacity(p);
printf("请输入姓名:> ");
scanf("%s", p->data[p->size].name);
printf("请输入电话:> ");
scanf("%s", p->data[p->size].tele);
printf("请输入地址:> ");
scanf("%s", p->data[p->size].addr);
p->size++;
puts("添加成功!");
system("pause");
}
删除前调用姓名查找函数FindByName(),找到需要删除的人的位置,再将其删除并将其后面的联系人补上来,再将size减少1个(很重要)!
void DelContact(Contact* p) {
int pos = 0;
int i = 0;
char name[MAX_NAME];
printf("请输入要删除人的姓名:> ");
scanf("%s", name);
pos = FindByName(p,name);
if (pos==-1) {
puts("查无此人!"); system("pause"); return;
}
else {
for (i = pos; i < p->size - 1; i++)
p->data[i] = p->data[i + 1];
p->size--;
}
puts("删除成功!");
system("pause");
}
遍历结构体成员,进行比较;若姓名一致,则返回该联系人的下标( i ),若找不到,则返回 (-1 )!
static int FindByName(const Contact* p, char name[MAX_NAME]) {
int i = 0;
for (i = 0; i < p->size; i++)
if (strcmp(p->data[i].name, name) == 0)
return i;
return -1;
}
调用姓名查找函数FindByName(),查找需要修改的人的位置,再调用具体修改函数DetModify(),修改具体信息!
void ModifyContact(Contact* p) {
int pos = 0;
char name[MAX_NAME];
printf("请输入需要修改人的姓名:> ");
scanf("%s", name);
pos = FindByName(p, name);
if (pos == -1) {
puts("查无此人!"); system("pause"); return;
}
else {
DetModify(p, pos);
}
}
采用菜单方式,选择需修改的具体内容!
void Mod_menu() {
puts("*********************************");
puts("*** 1、姓名 2、电话 3、地址 ***");
puts("*** 4、放弃修改 5、修改完毕 ***");
puts("*******************/*************");
}
void DetModify(Contact* p,int pos) {
while (1) {
system("cls");
int input = 0;
Mod_menu();
puts("\n信息如下:");
printf("%-20s\t%-20s\t%-20s\n", "名字", "电话", "地址");
printf("%-20s\t%-20s\t%-20s\n", p->data[pos].name,
p->data[pos].tele, p->data[pos].addr);
printf("\n请选择;> ");
scanf("%d", &input);
switch (input) {
case 1:printf("请输入姓名:> ");scanf("%s", p->data[pos].name);
puts("姓名修改完毕!"); system("pause"); break;
case 2:printf("请输入电话:> ");scanf("%s", p->data[pos].tele);
puts("电话修改完毕!"); system("pause"); break;
case 3:printf("请输入地址:> ");scanf("%s", p->data[pos].addr);
puts("地址修改完毕!"); system("pause"); break;
case 4:slect();
case 5:slect();
default:puts("选择错误,请重试!"); system("pause"); break;
}
}
}
调用姓名查找函数FindByName(),找到需查找的联系人的位置,再打印出来!
void SearchContact(const Contact* p) {
int pos = 0;
char name[MAX_NAME];
printf("请输入需要查找人的姓名:> ");
scanf("%s", name);
pos = FindByName(p,name);
if (pos == -1) {
puts("查无此人!"); system("pause"); return;
}
else {
printf("%-20s\t%-20s\t%-20s\n", "名字", "电话", "地址");
printf("%-20s\t%-20s\t%-20s\n", p->data[pos].name, p->data[pos].tele, p->data[pos].addr);
}
puts("显示完毕!");
system("pause");
}
显示之前调用排序函数SortContact(),将联系人排序,再打印出来!
void ShowContact(Contact* p) {
SortContact(p);
int i = 0;
if (p->size == 0)
puts("通讯录为空!");
else {
printf("%-20s\t%-20s\t%-20s\n", "名字", "电话", "地址");
for (i = 0; i < p->size; i++)
printf("%-20s\t%-20s\t%-20s\n",p->data[i].name,p->data[i].tele,p->data[i].addr);
}
puts("显示完毕!");
system("pause");
}
按姓名先后顺序进行排序!
static void SortContact(Contact* p) {
int i = 0, j = 0;
Info name;
for (i = 0; i < p->size; i++) {
for (j = 0; j < p->size - 1; j++) {
if (strcmp(p->data[j].name, p->data[j + 1].name) > 0) {
name = p->data[j], p->data[j] = p->data[j + 1],
p->data[j + 1] = name;
}
}
}
}
调用函数exit(0),退出程序之前,需调用通讯录销毁函数DestroyContact(),对开辟的动态内存空间进行释放!
exit(0);
销毁之前,需调用保存函数SaveContact(),将数据保存后再销毁!
void DestroyContact(Contact* p) {
SaveContact(p);
free(p->data);
p->data = NULL;
puts("通讯录销毁完毕!");
}
将联系人信息,采用二进制的形式保存到电脑文件中。
保存之前,需在电脑文件中找到“txl.c”文件的位置处,添加一个“contact.dat”文件用于存放联系人信息!
static void SaveContact(Contact* p) {
int i = 0;
FILE* fpWrite = fopen("contact.dat", "wb");
if (fpWrite == NULL) {
puts("无法保存!");
perror("contact.dat");
system("pause"); return;
}
for (i = 0; i < p->size; i++)
fwrite(&(p->data[i]), sizeof(Info), 1, fpWrite);
fclose(fpWrite);
fpWrite = NULL;
puts("保存完毕!");
}
Contact con;//con为通讯录,里面包含:data、size、capacity
int main() {
//初始化通讯录
InitContact(&con);
slect();
return 0;
}
void menu() {
puts("***************************************");
puts("*** 1、添加 2、删除 3、查找 4、修改 ***");
puts("*** 5、显示 0、退出 ***");
puts("***************************************");
printf("请选择:> ");
}
void slect() {
int input = 0;
while (1) {
system("cls");
menu();
scanf("%d", &input);
switch (input) {
case Add:AddContact(&con);
break;
case Del:DelContact(&con);
break;
case Search:SearchContact(&con);
break;
case Modify:ModifyContact(&con);
break;
case Show:ShowContact(&con);
break;
case Exit:DestroyContact(&con); puts("即将退出通讯录!");
system("pause"); exit(0);
break;
default:puts("选择错误,请重试!"); system("pause"); break;
}
}
}