目录
2、增加联系人 AddContact(Contact* p)
3、删除联系人 DelContact(Contact* p)
4、查找联系人信息 SearchContact(Contact* p)
5、修改联系人信息 ModifyContact(Contact* p)
6、排序联系人->按姓名?按年龄? SortContact(Contact* p)
7、 退出前保存文件 SaveContact(Contact* p)
8、 退出销毁(释放内存)DestroyContact(Contact* p)
一、总体思路
需要什么功能?->1、添加联系人(同时将之前存储号的通讯录文件加载进来) 2、删除联系人 3、查找联系人 4、修改联系人 5、显示所有联系人 6、排序联系人->按什么排序?->年龄?名字? 7、以文件形式保存 8、退出系统(释放空间)
需要存储什么信息?->1、姓名 2、年龄 3、性别 4、电话号码 5、地址
要实现的是静态的?(不可扩容)还是动态的?(自动扩容)->动态!
确定基本框架如下:
enum option//功能确定,用于后续Switch
{
Exit,
Add,
Del,
Search,
Modify,
Show,
Sort
};
typedef struct tp//存储信息
{
char name[10];
int age;
char sex[SEX];
char telp[TELP];
char addr[ADDR];
}tp;
typedef struct Contact//动态储存,方便扩容
{
tp* data;
int sz;
int capacity;
}Contact;
写出函数接口以确定整体的作用->确定以结构体指针的形式传参数
如下:
void InitContact(Contact* p);//初始化
void AddContact(Contact* p);//添加
void ShowContact(Contact* p);//显示
void DelContact(Contact* p);//删除
void SearchContact(Contact* p);//查找
void ModifyContact(Contact* p);//修改
void SortContact(Contact* p);//排序
void DestroyContact(Contact* p);//退出销毁
void SaveContact(Contact* p);//保存文件
接下来就是写下总体结构以及系统界面->确定以Switch函数来构造
如下:
void menu()
{
printf("**************************************\n");
printf("*****1、add *********2、del ******\n");
printf("*****3、search*********4、modify******\n");
printf("*****5、show *********6、sort ******\n");
printf("*****0、exit ********* ******\n");
printf("**************************************\n");
printf("请选择>");
}
void text()
{
int input = 0;
Contact p;
InitContact(&p);
do
{
menu();
scanf("%d", &input);
system("cls");
switch (input)
{
case Add:
AddContact(&p);
break;
case Del:
DelContact(&p);
break;
case Search:
SearchContact(&p);
break;
case Modify:
ModifyContact(&p);
break;
case Show:
ShowContact(&p);
break;
case Sort:
SortContact(&p);
//namesort1(&p);
break;
case Exit:
SaveContact(&p);
DestroyContact(&p);
printf("退出成功!\n");
break;
default:
printf("输入错误,请重新输入!\n");
break;
}
} while (input);
}
int main()
{
text();
return 0;
}
二、各个部分函数实现
1、初始化 InitContact(Contact* p)
void InitContact(Contact* p)
{
assert(p);
p->data = (tp*)malloc(sizeof(tp) * TELnum);//calloc
if (p->data == NULL)
{
perror("malloc");
return;
}
memset(p->data, 0, sizeof(p->data));
p->sz = 0;
p->capacity = TELnum;
//文件中保存的信息加载到通讯录中
LoadContact(p);
}
2、增加联系人 AddContact(Contact* p)
int CheckCapacity(Contact* pc)
{
if (pc->sz == pc->capacity)
{
tp* ptr = (tp*)realloc(pc->data, (pc->capacity + INC)*sizeof(tp));
if (ptr == NULL)
{
perror("CheckCapacity");
return 0;
}
else
{
pc->data = ptr;
pc->capacity += INC;
printf("增容成功\n");
return 1;
}
}
return 1;
}
void AddContact(Contact* p)
{
assert(p);
if (0==CheckCapacity(&p))
{
printf("通讯录已满!\n");
//EnContact(&p);
}
printf("\n请输入姓名>");
scanf("%s",p->data[p->sz].name);
printf("\n请输入年龄>");
scanf("%d", &p->data[p->sz].age);
printf("\n请输入性别>");
scanf("%s", p->data[p->sz].sex);
printf("\n请输入电话号码>");
scanf("%s", p->data[p->sz].telp);
printf("\n请输入地址>");
scanf("%s", p->data[p->sz].addr);
printf("在通讯录中成功添加%s的信息!\n", p->data[p->sz].name);
p->sz++;
}
3、删除联系人 DelContact(Contact* p)
void DelContact(Contact* p)
{
assert(p);
int flag = 0, de = 0;
if (p->sz == 0)
{
printf("通讯录为空!无法删除!\n");
return;
}
printf("输入删除信息的姓名>");
char arr[20]="0";
scanf("%s",&arr);
for (int i = 0; i < p->sz; i++)
{
if (strcmp(p->data[i].name, arr) == 0)//按照名字删除
{
flag = 1;
de = i;
break;
}
}
if (flag == 1)
{
for (int j = de; j < p->sz - 1; j++)
{
p->data[j] = p->data[j + 1];
}
p->sz--;
printf("成功删除!\n");
}
if (flag == 0)
printf("通讯录中未找到该联系人!\n");
}
4、查找联系人信息 SearchContact(Contact* p)
void SearchContact(Contact* p)
{
assert(p);
if (p->sz == 0)
{
printf("通讯录为空,无法查找!\n");
return;
}
printf("输入查找人的姓名>");
char arr[20]="0";
scanf("%s", arr);
for (int i = 0; i < p->sz; i++)
{
if (strcmp(p->data[i].name, arr) == 0)//通过姓名查找
{
printf("%-10s\t%-4s\t%-5s\t%-12s\t%-30s\n", "名字", "年龄", "性别", "电话", "地址");
printf("%-10s\t%-4d\t%-5s\t%-12s\t%-30s\n",
p->data[i].name,
p->data[i].age,
p->data[i].sex,
p->data[i].telp,
p->data[i].addr);
return;
}
}
printf("未找到该联系人!\n");
}
5、修改联系人信息 ModifyContact(Contact* p)
void ModifyContact(Contact* p)
{
assert(p);
if (p->sz == 0)
{
printf("通讯录为空,无法查找!\n");
return;
}
printf("输入要修改人的姓名>");
char arr[20]="0";
scanf("%s", &arr);
for (int i = 0; i < p->sz; i++)
{
if (strcmp(p->data[i].name, arr) == 0)//通过姓名修改
{
printf("\n请输入姓名>");
scanf("%s", p->data[i].name);
printf("\n请输入年龄>");
scanf("%d", &p->data[i].age);
printf("\n请输入性别>");
scanf("%s", p->data[i].sex);
printf("\n请输入电话号码>");
scanf("%s", p->data[i].telp);
printf("\n请输入地址>");
scanf("%s", p->data[i].addr);
printf("在通讯录中成功修改%s的信息!\n", p->data[i].name);
return;
}
}
printf("未找到要修改人%s的信息!", arr);
}
6、排序联系人->按姓名?按年龄? SortContact(Contact* p)
void SortContact(Contact* p)//懒得分装了0.0
{
assert(p);
if (p->sz == 0)
{
printf("\n通讯录为空,无法排序!!!\n");
return;
}
printf("请选择排序的形式>");
printf("\n*******************************");//提升菜单
printf("\n**1、按名字排序 2、按年龄排序**");
printf("\n*******************************\n");
int ret = 0;
scanf("%d", &ret);
if(ret==1)
{
printf("选择升序或降序>");
printf("\n**1、升**2、降**\n");
int re = 0;
Contact* pc = p;
scanf("%d", &re);
if (re == 1)//名字升序
{
int i = 0;
int j = 0;
tp tmp;
for (i = 0; i < p->sz - 1; i++)
{
int flag = 1;
for (j = 0; j < p->sz - i - 1; j++)
{
if (strcmp(p->data[j].name, p->data[j + 1].name) > 0)
{
tmp = p->data[j];
p->data[j] = p->data[j + 1];
p->data[j + 1] = tmp;
flag = 0;
}
}
if (flag == 1)
{
return;
}
}
printf("\n排序成功\n");
//namesort1(&pc);
}
else if (re == 2)//名字降序
{
int i = 0;
int j = 0;
tp tmp;
for (i = 0; i < p->sz - 1; i++)
{
int flag = 1;
for (j = 0; j < p->sz - i - 1; j++)
{
if (strcmp(p->data[j].name, p->data[j + 1].name) < 0)
{
tmp = p->data[j];
p->data[j] = p->data[j + 1];
p->data[j + 1] = tmp;
flag = 0;
}
}
if (flag == 1)
{
return;
}
}
printf("\n排序成功\n");
//namesort2(&pc);
}
else
{
printf("\n输入错误!\n");
}
//sort2(&p);
}
else if (ret == 2)
{
printf("选择升序或降序>");
printf("\n**1、升**2、降**\n");
int re = 0;
scanf("%d", &re);
switch (re)
{
case 1://年龄升序
for (int i = 0; i < p->sz - 1; i++)
{
for (int j = 0; j < p->sz - 1 - i; j++)
{
if (p->data[j].age > p->data[j + 1].age)
{
tp temp = p->data[j];
p->data[j] = p->data[j + 1];
p->data[j + 1] = temp;
}
}
}
printf("\n排序成功!\n");
break;
case 2://年龄降序
for (int i = 0; i < p->sz - 1; i++)
{
for (int j = 0; j < p->sz - 1 - i; j++)
{
if (p->data[j].age < p->data[j + 1].age)
{
tp temp = p->data[j];
p->data[j] = p->data[j + 1];
p->data[j + 1] = temp;
}
}
}
printf("\n排序成功!\n");
break;
default:
printf("\n输入错误!\n");
break;
}
}
else
{
printf("\n输入错误!\n");
}
}
7、 退出前保存文件 SaveContact(Contact* p)
void LoadContact(Contact* pc)//这里为上面第一小电中的加载函数
{
//打开文件
FILE* pf = fopen("contact.dat", "rb");
if (pf == NULL)
{
perror("LoadContact");
return;
}
//读文件
tp tmp = { 0 };
while (fread(&tmp, sizeof(tp), 1, pf))
{
if (0 == CheckCapacity(pc))
return;
pc->data[pc->sz] = tmp;
pc->sz++;
}
//关闭文件
fclose(pf);
pf = NULL;
}
void SaveContact(Contact* pc)
{
FILE* pf = fopen("contact.dat", "wb");
if (pf == NULL)
{
perror("SaveContact");
return;
}
//写数据
int i = 0;
for (i = 0; i < pc->sz; i++)
{
fwrite(pc->data + i, sizeof(tp), 1, pf);
}
//关闭文件
fclose(pf);
pf = NULL;
}
8、 退出销毁(释放内存)DestroyContact(Contact* p)
void DestroyContact(Contact* p)
{
free(p->data);
p->data = NULL;
p->capacity = 0;
p->sz = 0;
}
三、总体代码
1、rel.h
#pragma once
#define NAME 20
#define SEX 5
#define TELP 12
#define ADDR 30
#define TELnum 20
#define INC 20
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<assert.h>
enum option
{
Exit,
Add,
Del,
Search,
Modify,
Show,
Sort
};
typedef struct tp
{
char name[10];
int age;
char sex[SEX];
char telp[TELP];
char addr[ADDR];
}tp;
typedef struct Contact
{
tp* data;
int sz;
int capacity;
}Contact;
void InitContact(Contact* p);//初始化
void AddContact(Contact* p);//添加
void ShowContact(Contact* p);//显示
void DelContact(Contact* p);//删除
void SearchContact(Contact* p);//查找
void ModifyContact(Contact* p);//修改
void SortContact(Contact* p);//排序
void DestroyContact(Contact* p);//退出销毁
void SaveContact(Contact* p);//保存文件
2、rel.c
#define _CRT_SECURE_NO_WARNINGS 01
#include"rel.h"
int CheckCapacity(Contact* pc);
void LoadContact(Contact* pc)
{
//打开文件
FILE* pf = fopen("contact.dat", "rb");
if (pf == NULL)
{
perror("LoadContact");
return;
}
//读文件
tp tmp = { 0 };
while (fread(&tmp, sizeof(tp), 1, pf))
{
if (0 == CheckCapacity(pc))
return;
pc->data[pc->sz] = tmp;
pc->sz++;
}
//关闭文件
fclose(pf);
pf = NULL;
}
void InitContact(Contact* p)
{
assert(p);
p->data = (tp*)malloc(sizeof(tp) * TELnum);//calloc
if (p->data == NULL)
{
perror("malloc");
return;
}
memset(p->data, 0, sizeof(p->data));
p->sz = 0;
p->capacity = TELnum;
//文件中保存的信息加载到通讯录中
LoadContact(p);
}
int CheckCapacity(Contact* pc)
{
if (pc->sz == pc->capacity)
{
tp* ptr = (tp*)realloc(pc->data, (pc->capacity + INC)*sizeof(tp));
if (ptr == NULL)
{
perror("CheckCapacity");
return 0;
}
else
{
pc->data = ptr;
pc->capacity += INC;
printf("增容成功\n");
return 1;
}
}
return 1;
}
void AddContact(Contact* p)
{
assert(p);
if (0==CheckCapacity(&p))
{
printf("通讯录已满!\n");
//EnContact(&p);
}
printf("\n请输入姓名>");
scanf("%s",p->data[p->sz].name);
printf("\n请输入年龄>");
scanf("%d", &p->data[p->sz].age);
printf("\n请输入性别>");
scanf("%s", p->data[p->sz].sex);
printf("\n请输入电话号码>");
scanf("%s", p->data[p->sz].telp);
printf("\n请输入地址>");
scanf("%s", p->data[p->sz].addr);
printf("在通讯录中成功添加%s的信息!\n", p->data[p->sz].name);
p->sz++;
}
void ShowContact(Contact* p)
{
assert(p);
int i = 0;
if (p->sz == 0)
{
printf("通讯录为空!\n");
return;
}
printf("%-10s\t%-4s\t%-5s\t%-12s\t%-30s\n", "名字", "年龄", "性别", "电话", "地址");
while (i < p->sz)
{
printf("%-10s\t%-4d\t%-5s\t%-12s\t%-30s\n",
p->data[i].name,
p->data[i].age,
p->data[i].sex,
p->data[i].telp,
p->data[i].addr);
i++;
}
}
void DelContact(Contact* p)
{
assert(p);
int flag = 0, de = 0;
if (p->sz == 0)
{
printf("通讯录为空!无法删除!\n");
return;
}
printf("输入删除信息的姓名>");
char arr[20]="0";
scanf("%s",&arr);
for (int i = 0; i < p->sz; i++)
{
if (strcmp(p->data[i].name, arr) == 0)//按照名字删除
{
flag = 1;
de = i;
break;
}
}
if (flag == 1)
{
for (int j = de; j < p->sz - 1; j++)
{
p->data[j] = p->data[j + 1];
}
p->sz--;
printf("成功删除!\n");
}
if (flag == 0)
printf("通讯录中未找到该联系人!\n");
}
void SearchContact(Contact* p)
{
assert(p);
if (p->sz == 0)
{
printf("通讯录为空,无法查找!\n");
return;
}
printf("输入查找人的姓名>");
char arr[20]="0";
scanf("%s", arr);
for (int i = 0; i < p->sz; i++)
{
if (strcmp(p->data[i].name, arr) == 0)//通过姓名查找
{
printf("%-10s\t%-4s\t%-5s\t%-12s\t%-30s\n", "名字", "年龄", "性别", "电话", "地址");
printf("%-10s\t%-4d\t%-5s\t%-12s\t%-30s\n",
p->data[i].name,
p->data[i].age,
p->data[i].sex,
p->data[i].telp,
p->data[i].addr);
return;
}
}
printf("未找到该联系人!\n");
}
void ModifyContact(Contact* p)
{
assert(p);
if (p->sz == 0)
{
printf("通讯录为空,无法查找!\n");
return;
}
printf("输入要修改人的姓名>");
char arr[20]="0";
scanf("%s", &arr);
for (int i = 0; i < p->sz; i++)
{
if (strcmp(p->data[i].name, arr) == 0)//通过姓名修改
{
printf("\n请输入姓名>");
scanf("%s", p->data[i].name);
printf("\n请输入年龄>");
scanf("%d", &p->data[i].age);
printf("\n请输入性别>");
scanf("%s", p->data[i].sex);
printf("\n请输入电话号码>");
scanf("%s", p->data[i].telp);
printf("\n请输入地址>");
scanf("%s", p->data[i].addr);
printf("在通讯录中成功修改%s的信息!\n", p->data[i].name);
return;
}
}
printf("未找到要修改人%s的信息!", arr);
}
void SortContact(Contact* p)
{
assert(p);
if (p->sz == 0)
{
printf("\n通讯录为空,无法排序!!!\n");
return;
}
printf("请选择排序的形式>");
printf("\n*******************************");//提升菜单
printf("\n**1、按名字排序 2、按年龄排序**");
printf("\n*******************************\n");
int ret = 0;
scanf("%d", &ret);
if(ret==1)
{
printf("选择升序或降序>");
printf("\n**1、升**2、降**\n");
int re = 0;
Contact* pc = p;
scanf("%d", &re);
if (re == 1)//名字升序
{
int i = 0;
int j = 0;
tp tmp;
for (i = 0; i < p->sz - 1; i++)
{
int flag = 1;
for (j = 0; j < p->sz - i - 1; j++)
{
if (strcmp(p->data[j].name, p->data[j + 1].name) > 0)
{
tmp = p->data[j];
p->data[j] = p->data[j + 1];
p->data[j + 1] = tmp;
flag = 0;
}
}
if (flag == 1)
{
return;
}
}
printf("\n排序成功\n");
//namesort1(&pc);
}
else if (re == 2)//名字降序
{
int i = 0;
int j = 0;
tp tmp;
for (i = 0; i < p->sz - 1; i++)
{
int flag = 1;
for (j = 0; j < p->sz - i - 1; j++)
{
if (strcmp(p->data[j].name, p->data[j + 1].name) < 0)
{
tmp = p->data[j];
p->data[j] = p->data[j + 1];
p->data[j + 1] = tmp;
flag = 0;
}
}
if (flag == 1)
{
return;
}
}
printf("\n排序成功\n");
//namesort2(&pc);
}
else
{
printf("\n输入错误!\n");
}
//sort2(&p);
}
else if (ret == 2)
{
printf("选择升序或降序>");
printf("\n**1、升**2、降**\n");
int re = 0;
scanf("%d", &re);
switch (re)
{
case 1://年龄升序
for (int i = 0; i < p->sz - 1; i++)
{
for (int j = 0; j < p->sz - 1 - i; j++)
{
if (p->data[j].age > p->data[j + 1].age)
{
tp temp = p->data[j];
p->data[j] = p->data[j + 1];
p->data[j + 1] = temp;
}
}
}
printf("\n排序成功!\n");
break;
case 2://年龄降序
for (int i = 0; i < p->sz - 1; i++)
{
for (int j = 0; j < p->sz - 1 - i; j++)
{
if (p->data[j].age < p->data[j + 1].age)
{
tp temp = p->data[j];
p->data[j] = p->data[j + 1];
p->data[j + 1] = temp;
}
}
}
printf("\n排序成功!\n");
break;
default:
printf("\n输入错误!\n");
break;
}
}
else
{
printf("\n输入错误!\n");
}
}
void DestroyContact(Contact* p)
{
free(p->data);
p->data = NULL;
p->capacity = 0;
p->sz = 0;
}
void SaveContact(Contact* pc)
{
FILE* pf = fopen("contact.dat", "wb");
if (pf == NULL)
{
perror("SaveContact");
return;
}
//写数据
int i = 0;
for (i = 0; i < pc->sz; i++)
{
fwrite(pc->data + i, sizeof(tp), 1, pf);
}
//关闭文件
fclose(pf);
pf = NULL;
}
3、text.c
#define _CRT_SECURE_NO_WARNINGS 01
#include"rel.h"
void menu()
{
printf("**************************************\n");
printf("*****1、add *********2、del ******\n");
printf("*****3、search*********4、modify******\n");
printf("*****5、show *********6、sort ******\n");
printf("*****0、exit ********* ******\n");
printf("**************************************\n");
printf("请选择>");
}
void text()
{
int input = 0;
Contact p;
InitContact(&p);
do
{
menu();
scanf("%d", &input);
system("cls");
switch (input)
{
case Add:
AddContact(&p);
break;
case Del:
DelContact(&p);
break;
case Search:
SearchContact(&p);
break;
case Modify:
ModifyContact(&p);
break;
case Show:
ShowContact(&p);
break;
case Sort:
SortContact(&p);
//namesort1(&p);
break;
case Exit:
SaveContact(&p);
DestroyContact(&p);
printf("退出成功!\n");
break;
default:
printf("输入错误,请重新输入!\n");
break;
}
} while (input);
}
int main()
{
text();
return 0;
}