功能如下
初始化通讯录
首先,我们知道通讯录中的每个联系人的信息至少包括:姓名、年龄、性别、电话和住址。我们把这些练习人的特点,用一个结构体来描述:
//各个数据的最大容量
enum Max
{
Name_Max = 20,
Sex_Max = 6,
Tele_Max = 12,
Addr_Max = 30,
};
//联系人信息结构体
struct PeoInfo
{
char _name[Name_Max]; //姓名
int _age; //年龄
char _sex[Sex_Max]; //性别
char _tele[Tele_Max]; //电话
char _addr[Addr_Max]; //地址
};
由于我们写的通讯录是动态开辟,要知道当前存有多少个联系人,如果达到我们的最大容量,我们则要扩容。
//通讯录结构体
struct Addressbooks
{
struct PeoInfo *_data; //静态通讯录
int _size; //记录当前存有多少个联系人
int capacity; //最大容量
};
定义好结构体后,我们要先初始化起始联系人个数设为0,并给定一个初始的容量。当文件中存有联系人时,则把文件中的联系人录入进来。
//初始化
void InitPerson(struct Addressbooks* Pabs)
{
Pabs->_size = 0;
Pabs->capacity = 4;
Pabs->_data = (struct PeoInfo*)malloc(sizeof(struct PeoInfo)*Pabs->capacity);
FILE* FI = fopen("Contact_data.txt", "r");
if (FI == NULL)
{
printf("Init::%s\n", strerror(errno));
return;
}
while (fscanf(FI, "%s %s %d %s %s ", Pabs->_data[Pabs->_size]._name, Pabs->_data[Pabs->_size]._sex, &Pabs->_data[Pabs->_size]._age,
Pabs->_data[Pabs->_size]._tele, Pabs->_data[Pabs->_size]._addr)!=EOF)
{
increase_capacity(Pabs);
Pabs->_size++;
}
fclose(FI);
FI = NULL;
}
添加联系人
首先,想要添加一个联系人,如果当前容量已满,通过increase_capacity()函数来判断,如果满了我们则需要扩容。添加完一个联系人之后,存放到文件中
//判断是否要增容
void increase_capacity(struct Addressbooks*Pabs)
{
//判断电话通讯录是否已满
if (Pabs->_size == Pabs->capacity)
{
Pabs->capacity = Pabs->capacity + 1;
struct PeoInfo* temp = (struct PeoInfo*) realloc(Pabs->_data, sizeof(struct PeoInfo) * Pabs->capacity);
if (temp == NULL)
{
printf("内存扩充失败\n");
exit(-1);
}
printf("内存扩充成功\n");
Pabs->_data = temp;
}
}
//保存到文件
void SavePerson(struct Addressbooks* Pabs)
{
FILE* pf = fopen("Contact_data.txt", "w");
if (pf == NULL)
{
printf("Save::%s\n", strerror(errno));
return;
}
for (int i = 0; i <Pabs->_size; i++)
{
fprintf(pf, "%s %s %d %s %s ", Pabs->_data[i]._name, Pabs->_data[i]._sex, Pabs->_data[i]._age,
Pabs->_data[i]._tele, Pabs->_data[i]._addr);
}
fclose(pf);
pf = NULL;
}
//添加联系人
void addPerson(struct Addressbooks* Pabs)
{
increase_capacity(Pabs); //判断是否要增容函数
//姓名
printf("请输入名字:\n");
scanf("%s", Pabs->_data[Pabs->_size]._name);
//性别
printf("请输入性别: 男 or 女 \n");
while (true)
{
scanf("%s", Pabs->_data[Pabs->_size]._sex);
if (strcmp(Pabs->_data[Pabs->_size]._sex, "男") == 0)
{
break;
}
else if (strcmp(Pabs->_data[Pabs->_size]._sex, "女") == 0)
{
break;
}
printf("输入错误,请重现输入\n");
}
//年龄
printf("请输入年龄: \n");
scanf("%d", &Pabs->_data[Pabs->_size]._age);
//电话
printf("请输入联系电话:\n");
scanf("%s", Pabs->_data[Pabs->_size]._tele);
//住址
printf("请输入家庭住址:\n");
scanf("%s", Pabs->_data[Pabs->_size]._addr);
//更新通讯录的人数
FILE* PF = fopen("Contact_data.txt", "a");
if (PF == NULL)
{
printf("%s\n", strerror(errno));
return;
}
fprintf(PF,"%s %s %d %s %s\n", Pabs->_data[Pabs->_size]._name, Pabs->_data[Pabs->_size]._sex, Pabs->_data[Pabs->_size]._age,
Pabs->_data[Pabs->_size]._tele, Pabs->_data[Pabs->_size]._addr);
fclose(PF);
PF = NULL;
Pabs->_size++;
printf("添加成功\n");
system("pause"); //请按任意键继续
system("cls"); //清屏操作
}
删除联系人
先查找该联系人存不存在。如果存在,则删除并存入文件中,如果不存在,则不删除。
//检测联系人是否存在,如果存在,返回联系人所在数组中的具体位置,不存在返回-1
//参数1是通讯率 参数2是对比姓名
int isExist(struct Addressbooks* Pabs, char name[])
{
for (int i = 0; i < Pabs->_size; i++)
{
if (strcmp(Pabs->_data[i]._name, name) == 0)
{
return i;
}
}
return -1;
}
//删除联系人
void deletePerson(struct Addressbooks* Pabs)
{
char name[Name_Max];
printf("请输入您要删除的联系人姓名:\n");
scanf("%s", name);
int pos = isExist(Pabs, name);
if (pos == -1)
{
printf("想要删除的联系人不存在\n");
}
else
{
int i = 0;
for (i = pos; i < Pabs->_size - 1; i++)
{
Pabs->_data[i] = Pabs->_data[i + 1];
}
Pabs->_size--;
printf("删除成功\n");
}
SavePerson(Pabs);
system("pause");
system("cls");
}
查找联系人
查找你想要查找的姓名,如果存在,则显示该联系人的信息。
//查找联系人
void findPerson(const struct Addressbooks* Pabs)
{
char name[Name_Max];
printf("请输入您要查找的联系人姓名:\n");
scanf("%s", name);
int pos = isExist(Pabs, name);
if (pos == -1)
{
printf("查无此人\n");
}
else
{
printf("姓名:%-20s\t", Pabs->_data[pos]._name);
printf("年龄:%-2d\t", Pabs->_data[pos]._age);
printf("性别:%-5s\t", Pabs->_data[pos]._sex);
printf("电话:%-10s\t", Pabs->_data[pos]._tele);
printf("地址:%-10s\t", Pabs->_data[pos]._addr);
}
system("pause");
system("cls");
}
修改指定联系人
通过isExist函数来判断是否存在,如果存在,则修改该联系人的信息,修改完成后放入文件中。
//修改指定的联系人
void modifyPerson(struct Addressbooks* Pabs)
{
char name[Name_Max];
printf("请输入您要修改的联系人姓名:\n");
scanf("%s", name);
int pos = isExist(Pabs, name);
if (pos == -1)
{
printf("修改的联系人不存在\n");
}
else
{
//姓名
printf("请输入新的名字:\n");
scanf("%s", Pabs->_data[pos]._name);
//性别
printf("请输入新的性别: 男 or 女 \n");
while (true)
{
scanf("%s", Pabs->_data[pos]._sex);
if (strcmp(Pabs->_data[pos]._sex, "男") == 0)
{
break;
}
else if (strcmp(Pabs->_data[pos]._sex, "女") == 0)
{
break;
}
printf("输入错误,请重现输入\n");
}
//年龄
printf("请输入新的年龄: \n");
scanf("%d", &Pabs->_data[pos]._age);
//电话
printf("请输入联系新的电话:\n");
scanf("%s", Pabs->_data[pos]._tele);
//住址
printf("请输入新的家庭住址:\n");
scanf("%s", Pabs->_data[pos]._addr);
SavePerson(Pabs);
printf("修改成功\n");
system("pause"); //请按任意键继续
system("cls"); //清屏操作
}
}
显示联系人
首先先判断该通讯录中是否为空,如果为空则什么都不输出。
//显示所有联系人
void showPerson(const struct Addressbooks* Pabs)
{
if (Pabs->_size == 0)
{
printf("通讯录为空\n");
}
else
{
int i = 0;
for (i = 0; i < Pabs->_size; i++)
{
printf("姓名:%-20s\t", Pabs->_data[i]._name);
printf("性别:%-5s\t", Pabs->_data[i]._sex);
printf("年龄:%-2d\t", Pabs->_data[i]._age);
printf("电话:%-10s\t", Pabs->_data[i]._tele);
printf("地址:%-10s\t", Pabs->_data[i]._addr);
printf("\n");
}
}
system("pause");
system("cls");
}
对联系人按姓名排序
按姓名排序,排好序之后存放到文件中。
//排序联系人
void sortPerson(struct Addressbooks* Pabs)
{
for (int i = 0; i < Pabs->_size - 1; i++)
{
bool flag = true;
for (int j = 0; j < Pabs->_size - 1 - i; j++)
{
if (strcmp(Pabs->_data[j]._name, Pabs->_data[j + 1]._name) > 0)
{
struct PeoInfo temp = Pabs->_data[j];
Pabs->_data[j] = Pabs->_data[j + 1];
Pabs->_data[j + 1] = temp;
bool flag = false;
}
}
if (flag == true)
{
break;
}
}
SavePerson(Pabs);
printf("排序后的结果为:\n");
showPerson(Pabs);
}
清空联系人
清空联系人,并保存到文件中。
//清空所有联系人
void cleanPerson(struct Addressbooks* Pabs)
{
printf("请确定是否要清空所有联系人\n");
int select = 0;
printf("1---Yes\n");
printf("0---No\n");
scanf("%d", &select);
if (select == 1)
{
FILE* pf = fopen("Contact_data.txt", "w");
fclose(pf);
pf = NULL;
free(Pabs->_data);
Pabs->_size = 0; //将当前记录联系人数量置为0,做逻辑上的清空
Pabs->capacity = 0;
printf("通讯率已清空\n");
}
else
{
printf("您已取消清空联系人\n");
}
system("pause");
system("cls");
}
完成代码如下:
在Dynamic_Contact.h
中
#pragma once
#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<stdlib.h>
#include<stdbool.h>
#include<string.h>
#include<errno.h>
//各个数据的最大容量
enum Max
{
Name_Max = 20,
Sex_Max = 6,
Tele_Max = 12,
Addr_Max = 30,
};
//联系人信息结构体
struct PeoInfo
{
char _name[Name_Max]; //姓名
int _age; //年龄
char _sex[Sex_Max]; //性别
char _tele[Tele_Max]; //电话
char _addr[Addr_Max]; //地址
};
//通讯录结构体
struct Addressbooks
{
struct PeoInfo *_data; //静态通讯录
int _size; //记录当前存有多少个联系人
int capacity; //最大容量
};
//判断是否要增容
void increase_capacity(struct Addressbooks* Pabs);
//保存到文件
void SavePerson(struct Addressbooks*Pabs);
//初始化
void InitPerson(struct Addressbooks* Pabs);
//检测联系人是否存在,如果存在,返回联系人所在数组中的具体位置,不存在返回-1
//参数1是通讯率 参数2是对比姓名
int isExist(struct Addressbooks* Pabs, char name[]);
//添加联系人
void addPerson(struct Addressbooks* Pabs);
//显示所有联系人
void showPerson(const struct Addressbooks* Pabs);
//删除联系人
void deletePerson(struct Addressbooks* Pabs);
//查找联系人
void findPerson(const struct Addressbooks* Pabs);
//修改指定的联系人
void modifyPerson(struct Addressbooks* Pabs);
//清空所有联系人
void cleanPerson(struct Addressbooks* Pabs);
//排序联系人
void sortPerson(struct Addressbooks* Pabs);
在Dynamic_Contact.c
#include"Dynamic_Contact.h"
//判断是否要增容
void increase_capacity(struct Addressbooks*Pabs)
{
//判断电话通讯录是否已满
if (Pabs->_size == Pabs->capacity)
{
Pabs->capacity = Pabs->capacity + 1;
struct PeoInfo* temp = (struct PeoInfo*) realloc(Pabs->_data, sizeof(struct PeoInfo) * Pabs->capacity);
if (temp == NULL)
{
printf("内存扩充失败\n");
exit(-1);
}
printf("内存扩充成功\n");
Pabs->_data = temp;
}
}
//保存到文件
void SavePerson(struct Addressbooks* Pabs)
{
FILE* pf = fopen("Contact_data.txt", "w");
if (pf == NULL)
{
printf("Save::%s\n", strerror(errno));
return;
}
for (int i = 0; i <Pabs->_size; i++)
{
fprintf(pf, "%s %s %d %s %s ", Pabs->_data[i]._name, Pabs->_data[i]._sex, Pabs->_data[i]._age,
Pabs->_data[i]._tele, Pabs->_data[i]._addr);
}
fclose(pf);
pf = NULL;
}
//初始化
void InitPerson(struct Addressbooks* Pabs)
{
Pabs->_size = 0;
Pabs->capacity = 4;
Pabs->_data = (struct PeoInfo*)malloc(sizeof(struct PeoInfo)*Pabs->capacity);
FILE* FI = fopen("Contact_data.txt", "r");
if (FI == NULL)
{
printf("Init::%s\n", strerror(errno));
return;
}
while (fscanf(FI, "%s %s %d %s %s ", Pabs->_data[Pabs->_size]._name, Pabs->_data[Pabs->_size]._sex, &Pabs->_data[Pabs->_size]._age,
Pabs->_data[Pabs->_size]._tele, Pabs->_data[Pabs->_size]._addr)!=EOF)
{
increase_capacity(Pabs);
Pabs->_size++;
}
fclose(FI);
FI = NULL;
}
//添加联系人
void addPerson(struct Addressbooks* Pabs)
{
increase_capacity(Pabs);
//姓名
printf("请输入名字:\n");
scanf("%s", Pabs->_data[Pabs->_size]._name);
//性别
printf("请输入性别: 男 or 女 \n");
while (true)
{
scanf("%s", Pabs->_data[Pabs->_size]._sex);
if (strcmp(Pabs->_data[Pabs->_size]._sex, "男") == 0)
{
break;
}
else if (strcmp(Pabs->_data[Pabs->_size]._sex, "女") == 0)
{
break;
}
printf("输入错误,请重现输入\n");
}
//年龄
printf("请输入年龄: \n");
scanf("%d", &Pabs->_data[Pabs->_size]._age);
//电话
printf("请输入联系电话:\n");
scanf("%s", Pabs->_data[Pabs->_size]._tele);
//住址
printf("请输入家庭住址:\n");
scanf("%s", Pabs->_data[Pabs->_size]._addr);
//更新通讯录的人数
FILE* PF = fopen("Contact_data.txt", "a");
if (PF == NULL)
{
printf("%s\n", strerror(errno));
return;
}
fprintf(PF,"%s %s %d %s %s\n", Pabs->_data[Pabs->_size]._name, Pabs->_data[Pabs->_size]._sex, Pabs->_data[Pabs->_size]._age,
Pabs->_data[Pabs->_size]._tele, Pabs->_data[Pabs->_size]._addr);
fclose(PF);
PF = NULL;
Pabs->_size++;
printf("添加成功\n");
system("pause"); //请按任意键继续
system("cls"); //清屏操作
}
//显示所有联系人
void showPerson(const struct Addressbooks* Pabs)
{
if (Pabs->_size == 0)
{
printf("通讯录为空\n");
}
else
{
int i = 0;
for (i = 0; i < Pabs->_size; i++)
{
printf("姓名:%-20s\t", Pabs->_data[i]._name);
printf("性别:%-5s\t", Pabs->_data[i]._sex);
printf("年龄:%-2d\t", Pabs->_data[i]._age);
printf("电话:%-10s\t", Pabs->_data[i]._tele);
printf("地址:%-10s\t", Pabs->_data[i]._addr);
printf("\n");
}
}
system("pause");
system("cls");
}
//检测联系人是否存在,如果存在,返回联系人所在数组中的具体位置,不存在返回-1
//参数1是通讯率 参数2是对比姓名
int isExist(struct Addressbooks* Pabs, char name[])
{
for (int i = 0; i < Pabs->_size; i++)
{
if (strcmp(Pabs->_data[i]._name, name) == 0)
{
return i;
}
}
return -1;
}
//删除联系人
void deletePerson(struct Addressbooks* Pabs)
{
char name[Name_Max];
printf("请输入您要删除的联系人姓名:\n");
scanf("%s", name);
int pos = isExist(Pabs, name);
if (pos == -1)
{
printf("想要删除的联系人不存在\n");
}
else
{
int i = 0;
for (i = pos; i < Pabs->_size - 1; i++)
{
Pabs->_data[i] = Pabs->_data[i + 1];
}
Pabs->_size--;
printf("删除成功\n");
}
SavePerson(Pabs);
system("pause");
system("cls");
}
//查找联系人
void findPerson(const struct Addressbooks* Pabs)
{
char name[Name_Max];
printf("请输入您要查找的联系人姓名:\n");
scanf("%s", name);
int pos = isExist(Pabs, name);
if (pos == -1)
{
printf("查无此人\n");
}
else
{
printf("姓名:%-20s\t", Pabs->_data[pos]._name);
printf("年龄:%-2d\t", Pabs->_data[pos]._age);
printf("性别:%-5s\t", Pabs->_data[pos]._sex);
printf("电话:%-10s\t", Pabs->_data[pos]._tele);
printf("地址:%-10s\t", Pabs->_data[pos]._addr);
}
system("pause");
system("cls");
}
//修改指定的联系人
void modifyPerson(struct Addressbooks* Pabs)
{
char name[Name_Max];
printf("请输入您要修改的联系人姓名:\n");
scanf("%s", name);
int pos = isExist(Pabs, name);
if (pos == -1)
{
printf("修改的联系人不存在\n");
}
else
{
//姓名
printf("请输入新的名字:\n");
scanf("%s", Pabs->_data[pos]._name);
//性别
printf("请输入新的性别: 男 or 女 \n");
while (true)
{
scanf("%s", Pabs->_data[pos]._sex);
if (strcmp(Pabs->_data[pos]._sex, "男") == 0)
{
break;
}
else if (strcmp(Pabs->_data[pos]._sex, "女") == 0)
{
break;
}
printf("输入错误,请重现输入\n");
}
//年龄
printf("请输入新的年龄: \n");
scanf("%d", &Pabs->_data[pos]._age);
//电话
printf("请输入联系新的电话:\n");
scanf("%s", Pabs->_data[pos]._tele);
//住址
printf("请输入新的家庭住址:\n");
scanf("%s", Pabs->_data[pos]._addr);
SavePerson(Pabs);
printf("修改成功\n");
system("pause"); //请按任意键继续
system("cls"); //清屏操作
}
}
//清空所有联系人
void cleanPerson(struct Addressbooks* Pabs)
{
printf("请确定是否要清空所有联系人\n");
int select = 0;
printf("1---Yes\n");
printf("0---No\n");
scanf("%d", &select);
if (select == 1)
{
FILE* pf = fopen("Contact_data.txt", "w");
fclose(pf);
pf = NULL;
free(Pabs->_data);
Pabs->_size = 0; //将当前记录联系人数量置为0,做逻辑上的清空
Pabs->capacity = 0;
printf("通讯率已清空\n");
}
else
{
printf("您已取消清空联系人\n");
}
system("pause");
system("cls");
}
//排序联系人
void sortPerson(struct Addressbooks* Pabs)
{
for (int i = 0; i < Pabs->_size - 1; i++)
{
bool flag = true;
for (int j = 0; j < Pabs->_size - 1 - i; j++)
{
if (strcmp(Pabs->_data[j]._name, Pabs->_data[j + 1]._name) > 0)
{
struct PeoInfo temp = Pabs->_data[j];
Pabs->_data[j] = Pabs->_data[j + 1];
Pabs->_data[j + 1] = temp;
bool flag = false;
}
}
if (flag == true)
{
break;
}
}
SavePerson(Pabs);
printf("排序后的结果为:\n");
showPerson(Pabs);
}
在test.c中
#include"Dynamic_Contact.h"
//操作数
enum Option
{
Exit,
_Add,
_Show,
_Delete,
_Search,
_Modify,
_Clean,
_Sort
};
//菜单
void menu()
{
printf("***********************\n");
printf("*****1、添加联系人*****\n");
printf("*****2、显示联系人*****\n");
printf("*****3、删除联系人*****\n");
printf("*****4、查找联系人*****\n");
printf("*****5、修改联系人*****\n");
printf("*****6、清空联系人*****\n");
printf("*****7、排序联系人*****\n");
printf("*****0、退出通讯率*****\n");
printf("***********************\n");
}
void test()
{
struct Addressbooks abs;
//初始化
InitPerson(&abs);
while (true)
{
menu();
printf("请输入要选择的操作:\n");
int select = 0;
scanf("%d", &select);
switch (select)
{
case _Add:
addPerson(&abs);
break;
case _Show:
showPerson(&abs);
break;
case _Delete:
deletePerson(&abs);
break;
case _Search:
findPerson(&abs);
break;
case _Modify:
modifyPerson(&abs);
break;
case _Clean:
cleanPerson(&abs);
break;
case _Sort:
sortPerson(&abs);
break;
case Exit:
printf("您已退出程序,欢迎下次使用\n");
system("pause"); //请按任意键继续
exit(0);
default:
printf("输入错误,请重新输入\n");
system("pause"); //请按任意键继续
system("cls"); //清屏操作
break;
}
}
}
int main()
{
test();
return 0;
}
感觉大家的观看。