#include<stdio.h>
#include<stdlib.h>//改变颜色用的
#include<string.h>//字符串比较函数strmp
#include<assert.h>//断言函数
typedef struct person
{
char name[20];//姓名
int age;//年龄
char number[20];//电话号码
char adress[20];//家庭地址
char sex[5];//性别
}person;//联系人
typedef struct Contact
{
person* data;//存放数据 线性结构
int capacity;//当前通讯录容量
int sz;//实际有效信息数量 不是下标 是3就表示有三个数据
}Contact;
void InitContact(Contact* pc);//初始化通讯录
int addcapacity(Contact* pc);//判断是否扩容
void LoadContact(Contact* pc);//加载文件
void AddContact(Contact* pc);//添加联系人
int FindPeoInfo(char* name, Contact* pc);//查找联系人,返回其下标
void DeleteContact(Contact* pc);//删除联系人
void FindContact(Contact* pc);//查找联系人
void ModifyContact(Contact* pc);//修改联系人
void SaveContact(Contact* pc);//保存文件
void DestroyContact(Contact* pc);//空间销毁
int compare_Peo(const void* e1, const void* e2);//1.按名字对联系人排序
void SortContact(Contact* pc);//2.按名字对联系人排序
void ShowContact(Contact* pc);//显示通讯录
void screen ();//界面信息 返回的是哪个操作数字
int main()
{
Contact con;
InitContact(&con);//初始化通讯录
int input = 0;
do
{
screen();
printf("请选择->");
scanf("%d", &input);
switch (input)
{
case 1:
//增加联系人
AddContact(&con);
break;
case 2:
//删除联系人
DeleteContact(&con);
break;
case 3:
//查找联系人
FindContact(&con);
break;
case 4:
//修改联系人
ModifyContact(&con);
break;
case 5:
//对通讯录进行排序(按名字)
SortContact(&con);
break;
case 6:
//显示联系人
ShowContact(&con);
break;
case 7:
//保存文件
SaveContact(&con);
break;
case 8:
//加载文件
LoadContact(&con);
break;
case 9:
SaveContact(&con);
DestroyContact(&con);
printf("退出通讯录\n");
break;
default:
printf("选择错误,请重新选择!\n");
break;
}
}while (input);
return 0;
}
//对联系人进行排序(按名字)
int compare_Peo(const void* e1, const void* e2)
{
return strcmp(((person*)e1)->name,((person*)e2)->name);
}
void SortContact(Contact* pc)
{
qsort(pc->data, pc->sz, sizeof(pc->data[0]), compare_Peo);
printf("排序成功\n");
ShowContact(pc);
}
void DestroyContact(Contact* pc)//空间销毁
{
free(pc->data);
pc->data = NULL;
pc->capacity = 0;
pc->sz = 0;
}
//保存文件
void SaveContact(Contact* pc)
{
FILE* fp = fopen("contact1.txt", "wb");
if (fp == NULL)
{
printf("SaveContact::open for writting:%s", strerror(errno));
return;
}
//写入文件
int i = 0;
for (i = 0; i < pc->sz; i++)
{
fwrite(pc->data + i, sizeof(person), 1, fp);
}
//关闭文件
fclose(fp);
fp = NULL;
}
void ModifyContact(Contact* pc)//修改联系人
{
char name[20] = "0";
printf("请输入要修改的联系人姓名->");
scanf("%s", name);
int flag = FindPeoInfo(name, pc);
if (flag == -1)
{
printf("查无此人\n");
return;
}
else
{
int input = 0;
do
{
printf("1.姓名 2.年龄 3.性别 4.住址 5.电话 0.退出\n");
printf("请输入要修改的选项(按0退出修改)->");
scanf("%d", &input);
switch (input)
{
case 1:
printf("请输入改正后的姓名->");
scanf("%s", pc->data[flag].name);
break;
case 2:
printf("请输入改正后的年龄->");
scanf("%d", &(pc->data[flag].age));
break;
case 3:
printf("请输入改正后的性别->");
scanf("%s", pc->data[flag].sex);
break;
case 4:
printf("请输入改正后的住址->");
scanf("%s", pc->data[flag].adress);
break;
case 5:
printf("请输入改正后的电话->");
scanf("%s", pc->data[flag].number);
break;
case 0:
break;
default:
printf("输入错误,请重新输入!\n");
break;
}
} while(input);
printf("修改成功!\n");
}
}
void FindContact(Contact* pc)//查找联系人
{
char name[20] = "0";
printf("请输入要查找的联系人姓名->");
scanf("%s", name);//name是数组名不用加&
int flag = FindPeoInfo(name, pc);//返回下标
if (flag != -1)
{
printf("%-7s\t%-7s\t%-6s\t%-20s\t%-15s\n", "姓名", "性别", "年龄", "住址", "电话");//-7左对齐输出
printf("%-7s\t%-7s\t%-6d\t%-20s\t%-15s\n",
pc->data[flag].name, pc->data[flag].sex, pc->data[flag].age,
pc->data[flag].adress, pc->data[flag].number);
}
else
{
printf("查无此人!\n");
}
}
void DeleteContact(Contact* pc)//删除联系人
{
char name[20] = "0";
int i = 0;
printf("请输入要删除的联系人姓名->");
scanf("%s", name);
//查找联系人
int flag=FindPeoInfo(name,pc);//返回待查找联系人的下标
if (flag != -1)
{
for (i = flag; i < pc->sz-1; i++)
{
pc->data[i] = pc->data[i + 1];
}
pc->sz--;
printf("删除成功!\n");
}
else
{
printf("没有找到您需要删除的人!\n");
}
}
int FindPeoInfo(char* name, Contact* pc)//使用名字查找联系人,返回其下标
{
int i = 0;
for (i = 0; i < pc->sz; i++)
{
if (*name == *(pc->data[i].name))
{
return i;
}
}
return -1;
}
void AddContact(Contact* pc)
{
assert(pc);
int i=addcapacity(pc);//扩容成功返回1 容量未满也返回1
if (i)
{
printf("请输入姓名->");
scanf("%s", pc->data[pc->sz].name);
printf("请输入性别->");
scanf("%s", pc->data[pc->sz].sex);
printf("请输入年龄->");
scanf("%d", &(pc->data[pc->sz].age));
printf("请输入住址->");
scanf("%s", pc->data[pc->sz].adress);
printf("请输入电话->");
scanf("%s", pc->data[pc->sz].number);
pc->sz++;
printf("添加联系人成功!\n");
}
else
{
printf("添加联系人错误\n");
}
}
void ShowContact(Contact* pc)//显示通讯录
{
assert(pc);
if (pc->sz == 0)
{
printf("通讯录里无联系人!\n");
}
else
{
int i = 0;
printf("%-7s\t%-7s\t%-6s\t%-20s\t%-15s\n", "姓名", "性别", "年龄", "住址", "电话");
for (i = 0; i < pc->sz; i++)
{
printf("%-7s\t%-7s\t%-6d\t%-20s\t%-15s\n",
pc->data[i].name, pc->data[i].sex, pc->data[i].age,
pc->data[i].adress, pc->data[i].number);
}
}
}
void InitContact(Contact* pc)//初始化通讯录
{
assert(pc);//断言,如果错误就会终止执行
pc->sz = 0;
person *tmp = (person*)malloc(3 *sizeof(person));//申请3个person结构体
if (tmp != NULL)
{
pc->data = tmp;
}
else
{
printf("初始化错误\n");
return;
}
pc->capacity = 3;
LoadContact(pc);
}
//判断是否增容
int addcapacity(Contact* pc)
{
assert(pc);
if (pc->sz == pc->capacity)
{
person* tmp = (person*)realloc(pc->data, sizeof(person)*(pc->capacity+ 2));//realloc函数扩展malloc
if (tmp != NULL)
{
pc->data = tmp;
pc->capacity += 2;
//printf("增容成功\n");
return 1;
}
else
{
printf("扩容错误\n");
return 0;
}
}
return 1;
}
//加载文件
void LoadContact(Contact* pc)
{
//打开文件
FILE* pf = fopen("contact1.txt", "rb");//rb 二进制读写文件
if (pf == NULL)
{
printf("读写错误\n");
return;
}
//读文件
person tmp = { 0 };//tmp缓冲区
while (fread(&tmp, sizeof(person), 1, pf))//fread 从文件中读取二进制数据 (缓冲区 大小 个数 指针)
{
addcapacity(pc);
pc->data[pc->sz] = tmp;
pc->sz++;
}
//关闭文件
fclose(pf);
pf = NULL;
}
void screen ()//界面信息 返回的是哪个操作数字
{
system("color 2");
printf("----------------------------------------\n");
printf("| 电话号码查询系统 |\n");
printf("|--------------------------------------|\n");
printf("| |\n");
printf("| 1.添加联系人 |\n");
printf("| |\n");
printf("| 2.删除联系人 |\n");
printf("| |\n");
printf("| 3.查找联系人 |\n");
printf("| |\n");
printf("| 4,修改联系人 |\n");
printf("| |\n");
printf("| 5.对通讯录进行排序 |\n");
printf("| |\n");
printf("| 6.显示联系人 |\n");
printf("| |\n");
printf("| 7.保存通讯录 |\n");
printf("| |\n");
printf("| 8.加载通讯录 |\n");
printf("| |\n");
printf("| 9.退出通讯录 |\n");
printf("----------------------------------------\n");
printf("请选择操作:");
}