功能要求
1.能够存储1000个联系人的信息。
2.联系人信息包括姓名、年龄、性别、手机号码、地址。
3能够增加联系人。
4能查找指定联系人信息。
5能删除指定联系人信息。
6能够修改指定联系人信息。
7当输入完成后能保存联系人信息。
8能根据姓名排序
思路
采用多文件编程的方法,分为一个头文件和两个源文件。
1contact.h 头文件用来定义函数,引用头文件,替换字符。
2test.c源文件,主函数放在这里。
3contact.c具体的函数功能,放在这里。
在.c文件中加入#include“contact.h”,实现跨文件编程。
打印菜单
当程序开始运行的时候,首先输出可供选择的信息,直观方便。
这部分放在test.c文件中。
void menu()
{
printf("***********************************\n");
printf("*** 简单通讯录 **********\n");
printf("********1.adding contacts**********\n");
printf("********2.searching contacts*******\n");
printf("********3.dele contacts************\n");
printf("********4.modyfi contacts**********\n");
printf("********5.cls**********************\n");
printf("********6.sort contacts************\n");
printf("********7.print contacts***********\n");
printf("********8.save*********************\n");
printf("********0.exit*********************\n");
}
一共九个选项,分别是:
1.增加联系人。
2.查找联系人。
3.删除联系人。
4.修改联系人。
5.清屏。
6.对联系人排序。
7.保存通讯录
0.离开
宏定义
为了方便修改,在编程的过程中方便输入,采用宏定义的方式替换关键字。这部分放在头文件中。
#define _CRT_SECURE_NO_WARNINGS 1
//vs编译器对一些库函数会发出警告,这里用来去除警告。
#define maxName 20
#define maxSex 10
#define maxPhoneNumber 15
#define maxAddress 10
#define maxPersonalInfomation 1000
//数组元素个数,方便修改
枚举
枚举定义常量,方便选择。
enum input
{
exit1,
addingContacts,
searchingContacts,
deleContacts,
modyfiContacts,
cls,
sortcontacts,
printcotacts,
save
};
创建数组和初始化
contact.c文件中。
//一个联系人内包含的信息
typedef struct personalInfomation
{
char name[maxName];
int age;
char sex[maxSex];
char phoneNumber[maxPhoneNumber];
char address[maxAddress];
}personalInfomation;
typedef struct contact
{
personalInfomation date[maxPersonalInfomation];
int index;//创建一个带下标变量的结构体。
}contact;
通过结构体创建数组。
利用typedef,将结构体替换成更为方便的表示方法。
test.c文件中
contact list;//创建结构体变量list
initializeList(&list);//对结构体变量进行初始化
初始化,contact.c文件中。
void initializeList(contact* pc)
{
pc->index = 0;
memset(pc->date, 0, sizeof(pc->date));//内存操作库函数
}
输入,进行选择。
test.c文件中。
int input = 0;//input变量初始化
do
{
printf("请输入数字>:");
scanf("%d", &input);
switch (input)
{
case exit1:
break;
case addingContacts:
add(&list);//增加联系人函数
break;
case searchingContacts:
search(&list);//查找联系人函数
break;
case deleContacts:
dele(&list);//删除联系人函数
break;
case modyfiContacts:
mod(&list);//修改联系人函数
break;
case cls:
system("cls");//清屏库函数
break;
case sortcontacts:
sort(&list);//排序函数
break;
case printcotacts:
print(&list);//打印函数
break;
case save:
saveFile(&list);//保存函数
break;
default:
printf("非法字符,重新输入\n");
break;
}
} while (input);//input为0,表达式为假,退出
return 0;
使用do…while循环,判断条件为input的值,当输入0选择exit的时候,表达式为假,退出。当选择其他功能的时候,不会退出,多次选择。
用函数实现功能
首先,在头文件中,放入函数声明。
//初始化通讯录
void initializeList(contact* list);
//添加联系人,并存储在数组中
void add(contact* pa);
//输入姓名,查找数组中联系人全部信息
void search(contact* pa);
//打印函数,打印通讯录数组的内容
void print(contact* pa);
//输入姓名,删除指定联系人
void dele(contact* pa);
//输入姓名,修改联系人的其他信息
void mod(contact* pa);
//给存储在数组中的联系人排序
void sort(contact* pa);
//保存联系人
void saveFile(contact*pa);
然后,在contact.c文件中
//find函数,输入数组和名字,输出
static int find( const contact*pa,char *names)
{
for (int i = 0; i < pa->index ; i++)
{
if (strcmp(pa->date[i].name,names)==0)
{
return i;
}
}
return -1;
}
//添加联系人,并存储在数组中
void add(contact* pa)
{
if (pa->index == maxPersonalInfomation)
{
printf("通讯录已满");
return;
}
printf("请输入姓名>:");
scanf("%s",pa->date[pa->index].name);
printf("请输入年龄>:");
scanf("%d", &pa->date[pa->index].age);
printf("请输入性别>:");
scanf("%s", pa->date[pa->index].sex);
printf("请输入电话号码>:");
scanf("%s", pa->date[pa->index].phoneNumber);
printf("请输入地址>:");
scanf("%s", pa->date[pa->index].address);
pa->index++;
printf("通讯录添加成功\n");
}
输入姓名,查找数组中联系人全部信息
void search(contact* pa)
{
int ret = 0;
char Fintname[maxName]={0};
printf("请输入查询姓名>:");
scanf("%s", Fintname);
ret = find(pa, Fintname);
if ( ret== -1)
{
printf("没找到\n");
}
else
{
printf("找到了\n");
printf("姓名:%s\t年龄:%d\t:性别:%s\t电话号码:%s\t:地址:%s\n", pa->date[ret].name,
pa->date[ret].age,
pa->date[ret].sex,
pa->date[ret].phoneNumber,
pa->date[ret].address);
}
}
//打印函数,打印通讯录数组的内容
void print(contact* pa)
{
for (int i = 0; i < pa->index; i++)
{
printf("%d:姓名:%s\t年龄:%d\t:性别:%s\t电话号码:%s\t:地址:%s\n", i+1,pa->date[i].name,
pa->date[i].age,
pa->date[i].sex,
pa->date[i].phoneNumber,
pa->date[i].address);
}
}
//输入姓名,删除指定联系人
void dele(contact* pa)
{
int i = 0;
if (pa->index == 0)
{
printf("通讯录为空,不需要删除\n");
}
int ret = 0;
char Fintname[maxName] = { 0 };
printf("请输入要删除联系人姓名>:");
scanf("%s", Fintname);
ret = find(pa, Fintname);
if (ret == -1)
{
printf("没找到\n");
}
else
{
for (i = ret; i < pa->index; i++)
{
pa->date[ret + i] = pa->date[ret + i + 1];
pa->index--;
}
printf("删除成功\n");
}
}
//输入姓名,修改联系人的其他信息
void mod(contact* pa)
{
int ret = 0;
char Fintname[maxName] = { 0 };
printf("请输入修改姓名>:");
scanf("%s", Fintname);
ret = find(pa, Fintname);
if (ret == -1)
{
printf("没找到\n");
}
else
{ printf("找到了\n");
printf("请修改姓名>:");
scanf("%s", pa->date[ret].name);
printf("请修改年龄>:");
scanf("%d", &pa->date[ret].age);
printf("请修改性别>:");
scanf("%s", pa->date[ret].sex);
printf("请修改电话号码>:");
scanf("%s", pa->date[ret].phoneNumber);
printf("请修改地址>:");
scanf("%s", pa->date[ret].address);
printf("联系人修改成功\n");
}
}
//给存储在数组中的联系人排序
void sort(contact* pa)
{
int j = 0;
int i = 0;
personalInfomation temp;
for (j=0;j<(pa->index-1);j++)
{
for (i = 0; i <(pa->index-j-1); i++)
{
if (strcmp(pa->date[i].name, pa->date[i+1].name) > 0)
{
temp = pa->date[i];
pa->date[i] = pa->date[i + 1];
pa->date[i + 1] = temp;
}
}
}
printf("排序完成\n");
}
//保存联系人
void saveFile(contact* pa)
{
int i = 0;
FILE* fp;
fp = fopen("address book.txt", "w+");
for (i = 0; i < pa->index; i++)
{
fprintf(fp,"%s\t""%d\t""%s\t""%s\t""%s\n", pa->date[i].name,
pa->date[i].age,
pa->date[i].sex,
pa->date[i].phoneNumber,
pa->date[i].address);
}
fclose(fp);
printf("保存成功\n");
}
改进方向
1在栈区中创建1000个元素的数组,占据过大内存,可改成链表方式视线,让还没有存入的空间不占据内存。
2增加读取功能,能够将之前保存的通讯录联系人内容读取。