目录
通讯录 - 静态版本1.通讯录能存放1000个人的信息个人的信息:姓名+年龄+性别+电话+地址2.增加人的信息3.修改指定人的信息4.删除指定人的信息5.查找指定人的信息6.排序通讯录的信息
版本2:动态增长的版本1>通讯录初始化,能存放3个人的信息2>当空间存放满的时候,我们增加2个信息
对与不怎么熟悉的人建议先对照静态通讯录,再对照动态通讯录的注释代码进行练习
3.函数的实现(Contact.c)对memset不了解的可以看这里
通讯录 - 静态版本
1.通讯录能存放1000个人的信息
个人的信息:姓名+年龄+性别+电话+地址
2.增加人的信息
3.修改指定人的信息
4.删除指定人的信息
5.查找指定人的信息
6.排序通讯录的信息版本2:
动态增长的版本
1>通讯录初始化,能存放3个人的信息
2>当空间存放满的时候,我们增加2个信息3>可以保存添加的内容到文件中,下次运行可以显示上次的内容
1.通讯录(静态)
为方便通讯录的实现
1.函数的实现放在Contact.c文件中
2.函数的声明及定义方在Contact.h头文件中
3.通讯录实现的逻辑代码放到test.c文件
对与不怎么熟悉的人建议先对照静态通讯录,再对照动态通讯录的注释代码进行练习
1.逻辑代码(test.c)
void menu()//菜单
{
printf("********************************\n");
printf("*********1.add 2.del *********\n");
printf("*******3.search 4.modift *********\n");
printf("********5.sort 6.print ******\n");
printf("***********0.exit************\n");
printf("********************************\n");
}
enum option //枚举类型
{
//起始值默认值为0,后一个数是前一个数加1
EXIT, //0
ADD, //1
DEL, //2
SEARCH, //3
MODIFT, //4
SORT, //5
PRINT //6
};
int main()
{
int input = 0;
//创建通讯录
//通讯录当前有几个元素
Contact con;//通讯录
//初始化通讯录
InitContact(&con);
do
{
menu();
printf("请选择:>");
scanf("%d",&input);
switch (input)
{
case ADD:
//添加人的信息
AddContact(&con);
break;
case DEL:
//删除人的信息
DelContact(&con);
break;
case SEARCH:
//查找人的信息
FindContact(&con);
break;
case MODIFT:
//修改人的信息
ModiftyContact(&con);
break;
case SORT:
//排序人的信息
SortContact(&con);
break;
case PRINT:
//打印人的信息
PrintContact(&con);
break;
case EXIT:
printf("退出通讯录\n");
break;
default:
printf("选择错误请从新选择\n");
break;
}
} while (input);
}
2.函数的声明及定义(Contact.h)
对memset不了解的可以看这里
#pragma once
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
//为了增强函数可变性,定义宏
#define MAX 1000
#define MAX_NAME 20
#define MAX_SEX 10
#define MAX_TELE 12
#define MAX_ADDR 30
//类型的定义
typedef struct PeoInfo
{
char name[MAX_NAME];
char sex[MAX_SEX];
int age;
char tele[MAX_TELE];
char addr[MAX_ADDR];
}PeoInfo;
//通讯录 - 静态
typedef struct Contact
{
PeoInfo data[MAX];//存放添加进来的人的信息
int sz;//记录的是当前通讯录中有效信息的个数
}Contact;
//初始化通讯录
void InitContact(Contact* pc);
//添加人的信息
void AddContact(Contact* pc);
//打印人的信息
void PrintContact(const Contact* pc);
//删除人的信息
void DelContact(Contact* pc);
//查找人的信息
void FindContact(const Contact* pc);
//查找人的姓名
int FindByName(const Contact* pc,char name[]);
//修改人的信息
void ModiftyContact(Contact* pc);
//排序通讯录
void SortContact(Contact* pc);
//按年龄排序
void SortContact(Contact* ps);
3.函数的实现(Contact.c)对memset不了解的可以看这里
#define _CRT_SECURE_NO_WARNINGS 1
#include "Contact.h"
//初始化
void InitContact(Contact* pc)
{
pc->sz = 0;
memset(pc->data,0,sizeof(pc->data));
}
//静态版本 - 增加联系人
void AddContact(Contact* pc)
{
if (pc->sz == MAX)
{
printf("已经满了,不要再放了!!!");
}
//增加一个人的信息
printf("请输入名字:>");
scanf("%s",pc->data[pc->sz].name);
printf("请输入年龄:>");
scanf("%d",&(pc->data[pc->sz].age));
printf("请输入性别:>");
scanf("%s", pc->data[pc->sz].sex);
printf("请输入电话:>");
scanf("%s", pc->data[pc->sz].tele);
printf("请输入地址:>");
scanf("%s", pc->data[pc->sz].addr);
pc->sz++;
printf("增加成功\n");
}
//按年龄排序
void SortContact(Contact* ps)
{
int i = 0;
int j = 0;
int flag = 1;
PeoInfo tmp;
for (i = 0; i < ps->sz - 1; i++)
{
for (j = 0; j < ps->sz - i - 1; j++)
{
if ((ps->data[j].age) - (ps->data[j + 1].age)>0)//升序
{
tmp = ps->data[j];
ps->data[j] = ps->data[j + 1];
ps->data[j + 1] = tmp;
flag = 0;
}
}
if (flag == 1)
{
break;
}
}
PrintContact(ps);
printf("排序成功");
}
//显示全部信息
void PrintContact(const Contact* pc)
{
int i = 0;
//打印标题
printf("%-20s\t%-5s\t%-8s\t%-12s\t%-20s\n", "名字", "年龄", "性别", "电话", "地址");
//打印数据
for (i = 0; i < pc->sz; i++)
{
printf("%-20s\t%-5d\t%-8s\t%-12s\t%-20s\n",
pc->data[i].name,
pc->data[i].age,
pc->data[i].sex,
pc->data[i].tele,
pc->data[i].addr);
}
}
//由于删除,查询等会使用到故单独封装为一个函数,增强函数的复用性(static:限制只在本文件中被调用)
static int FindByName(const Contact* pc, char name[])
{
for (int i = 0; i < pc->sz; i++)
{
if (strcmp(name, pc->data[i].name) == 0)
return i;
}
return -1;//找不到
}
//删除
void DelContact(Contact* pc)
{
if (pc->sz == 0)
{
printf("通讯录为空,无需查找\n");
return;
}
char name[MAX_NAME] = { 0 };
printf("请输入要删除人的名字:>");
scanf("%s", name);
//1.查找要删除的人
//有/没有
int pos = FindByName(pc, name);
if (pos == -1)
{
printf("要删除的人不存在:>");
return;
}
else
{
for (int i = pos; i < pc->sz - 1; i++)
{
pc->data[i] = pc->data[i + 1];
}
}
pc->sz--;
printf("删除成功\n");
}
//查询
void FindContact(const Contact* pc)
{
char name[MAX_NAME] = { 0 };
printf("请输入要查找人的名字:>");
scanf("%s", name);
//1.查找指定人的信息
//有/没有
int pos = FindByName(pc, name);
if (pos == -1)
{
printf("要查找的人不存在:>");
return;
}
else
{
printf("%-20s\t%-5s\t%-8s\t%-12s\t%-20s\n", "名字", "年龄", "性别", "电话", "地址");
printf("%-20s\t%-5d\t%-8s\t%-12s\t%-20s\n",
pc->data[pos].name,
pc->data[pos].age,
pc->data[pos].sex,
pc->data[pos].tele,
pc->data[pos].addr);
}
}
//修改
void ModiftyContact(Contact* pc)
{
char name[MAX_NAME] = { 0 };
printf("请输入要修改人的名字:>");
scanf("%s", name);
//1.查找修改人的信息
//有/没有
int pos = FindByName(pc, name);
if (pos == -1)
{
printf("要修改的人不存在:>");
return;
}
else
{
printf("请输入名字:>");
scanf("%s", pc->data[pos].name);
printf("请输入年龄:>");
scanf("%d", &(pc->data[pos].age));
printf("请输入性别:>");
scanf("%s", pc->data[pos].sex);
printf("请输入电话:>");
scanf("%s", pc->data[pos].tele);
printf("请输入地址:>");
scanf("%s", pc->data[pos].addr);
printf("修改成功");
}
}
2.通讯录(动态)
1.逻辑代码(test.c)
#define _CRT_SECURE_NO_WARNINGS 1
#include "Contact.h"
void menu()
{
printf("*****************************************************\n");
printf("**********1.add 2.del **********\n");
printf("**********3.search 4.modifity**********\n");
printf("**********5.print 6.save *************\n");
printf("**********7.sort 0.exit **********\n");
printf("*****************************************************\n");
}
enum Option
{
EXIT,
ADD,
DEL,
SEARCH,
MODIFITY,
PRINT,
SAVE,
SORT
};
int main()
{
//创建通讯录
Contact con;//通讯录
InitContact(&con);//初始化通讯录
int input = 0;
do
{
menu();
scanf("%d", &input);
switch (input)
{
case ADD:
//添加
AddContact(&con);
break;
case DEL:
//删除
DelContact(&con);
break;
case SEARCH:
//查询
SearchContact(&con);
break;
case MODIFITY:
//修改
ModifityContact(&con);
break;
case PRINT:
//显示
PrintContact(&con);
break;
case SORT:
SortContact(&con);
break;
case SAVE:
SaveContact(&con);
break;
case EXIT:
//保存当前保存数据到文件
SaveContact(&con);
DestroyContact(&con);
break;
default:
printf("输入不合法,请重新输入->");
break;
}
} while (input);
}
2.函数的声明及定义(Contact.h)
#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define NAME 10
#define SEX 10
#define ADDR 30
#define TEL 12
#define DEFAULT_SZ 3//动态通讯录 - 初始容量
#define INC_SC 2//当通讯录中有效信息的个数超过,最大信息个数时动态开辟内存,每次增加2个人的信息容量
typedef struct PeoInfo
{
char name[NAME];
int age;
char sex[SEX];
char addr[ADDR];
char tel[TEL];
}PeoInfo;
//静态 - 通讯录
//typedef struct Contact
//{
// int sz;
// PeoInfo data[MAX];
//}Contact;
//动态 - 通讯录
typedef struct Contact
{
int sz;//当前信息个数
int capacity;//最大容量
PeoInfo* data;
}Contact;
void InitContact(Contact* pc);//初始化通讯录
void AddContact(Contact* pc);//添加
void PrintContact(Contact* pc);//打印
void DelContact(Contact* pc);//删除
int FindByName(Contact* pc,char name[]);//查找姓名返回对应的索引值
void SearchContact(Contact* pc);//查询姓名并显示对应信息
void ModifityContact(Contact* pc);//修改指定姓名所在行的内容
void DestroyContact(Contact* pc);//销毁
void SortContact(Contact* pc);//按年龄排序
void SaveContact(Contact* pc);//保存到文件中
int CheckCapacity(Contact* pc);//判断是否达到容量,达到则增加两个人的信息容量
void LoadContact(Contact* pc);//加载内容
3.函数的实现(Contact.c)
#define _CRT_SECURE_NO_WARNINGS 1
#include "Contact.h"
//动态
void InitContact(Contact* pc)
{
pc->data = (PeoInfo*)malloc(DEFAULT_SZ * sizeof(PeoInfo));
if (pc->data == NULL)
{
perror("InitContact");
return;
}
pc->sz = 0;
pc->capacity = DEFAULT_SZ;
//加载联系人
LoadContact(pc);
}
//判断是否达到容量,若达到进行扩容
int CheckCapacity(struct Contact* ps)
{
if (ps->sz == ps->capacity)
{
//当通讯录当前人数等于容量时进行扩容一次默认扩充两个空间
//参数1.要调整的内存地址 2.调整之后的大小(单位字节)
PeoInfo* str = (PeoInfo*)realloc(ps->data, (ps->capacity + 2) * sizeof(struct PeoInfo));
if (str != NULL)
{
ps->data = str;//开辟成功把地址赋给原来的指针继续维护
ps->capacity += 2;//通讯录的容量加2
printf("增容成功\n");
return 1;
}
else
{
printf("扩容失败\n");
return -1;
}
}
}
//动态添加
void AddContact(Contact* pc)
{
int ret = CheckCapacity(pc);
if (ret == -1)
{
printf("添加失败\n");
}
else
{
printf("亲输入姓名->");
scanf("%s", pc->data[pc->sz].name);
printf("亲输入年龄->");
scanf("%d", &(pc->data[pc->sz].age));
printf("亲输入性别->");
scanf("%s", pc->data[pc->sz].sex);
printf("亲输入电话号->");
scanf("%s", pc->data[pc->sz].tel);
printf("亲输入地址->");
scanf("%s", pc->data[pc->sz].addr);
pc->sz++;
printf("添加成功\n");
}
}
//排序
void SortContact(Contact* pc)
{
int i = 0;
for (i = 0; i < pc->sz - 1; i++)
{
int j = 0;
for (j = 0; j < pc->sz - 1 - i; j++)
{
if (pc->data[j].age > pc->data[j + 1].age)
{
PeoInfo tmp = pc->data[j];
pc->data[j] = pc->data[j + 1];
pc->data[j + 1] = tmp;
}
}
}
}
//保存
void SaveContact(Contact* pc)
{
int i = 0;
//打开文件
FILE* pfwrite = fopen("contact.dat", "wb");
if (pfwrite == NULL)//打开文件失败
{
printf("SaveContact:: %s", strerror(errno));
return;//返回而不返回值 提前结束函数
}
for (i = 0; i < pc->sz; i++)
{
//将已有的联系人依次保存到文件
fwrite(&(pc->data[i]), sizeof(PeoInfo), 1, pfwrite);
}
//关闭文件
fclose(pfwrite);
pfwrite = NULL;
}
//加载联系人
void LoadContact(Contact* pc)
{
PeoInfo tmp;//创建一个联系人的临时变量用来接收从文件读取的信息
//打开文件
FILE* pfread = fopen("contact.dat", "rb");
if (pfread == NULL)//打开文件失败
{
//printf("LoadContact: %s", strerror(errno));
perror("LoadContact:"); //打印生成的错误说明
return;//返回而不返回值 提前结束函数
}
//fread函数返回值是 读取到的元素个数,这里采用一个一个读取
//若文件有数据,读取一个fread,函数返回值为1进入循环
//若文件数据已被读取完毕则返回0,退出循环
while (fread(&tmp, sizeof(PeoInfo), 1, pfread))
{
CheckCapacity(pc);//存放前检测通讯录容量,不够就扩容
//初始化通讯录时size为0
pc->data[pc->sz] = tmp;//将读出的数据存放进通讯录
pc->sz++;
}
//关闭文件
fclose(pfread);
pfread = NULL;
}
//销毁通讯录,返还内存给系统(程序结束时也会自动返还内存给系统)
void DestroyContact(Contact* pc)
{
free(pc->data);
pc->data = NULL;
pc->sz = 0;
pc->capacity = 0;
}
void PrintContact(Contact* pc)
{
int i = 0;
//打印标题
printf("%-20s\t%-5s\t%-8s\t%-12s\t%-20s\n", "名字", "年龄", "性别", "电话", "地址");
//打印数据
for (i = 0; i < pc->sz; i++)
{
printf("%-20s\t%-5d\t%-8s\t%-12s\t%-20s\n",
pc->data[i].name,
pc->data[i].age,
pc->data[i].sex,
pc->data[i].tel,
pc->data[i].addr);
}
}
int FindByName(Contact* pc, char name[])
{
int j = 0;
for (j = 0; j < pc->sz; j++)
{
if (strcmp(name, pc->data[j].name) == 0)
return j;
}
return -1;
}
void DelContact(Contact* pc)
{
char name[NAME] = { 0 };
printf("亲输入删除人的姓名->");
scanf("%s", name);
int ret = FindByName(pc, name);
if (ret == -1)
return;
int i = 0;
for (i = ret; i < pc->sz - 1; i++)
{
pc->data[i] = pc->data[i + 1];
}
printf("删除成功->");
pc->sz--;
}
void SearchContact(Contact* pc)
{
char name[NAME] = { 0 };
printf("亲输入查询人的姓名->");
scanf("%s", name);
int ret = FindByName(pc, name);
if (ret == -1)
{
printf("查无此人->");
return;
}
int i = ret;
//打印数据
printf("%-20s\t%-5d\t%-8s\t%-12s\t%-20s\n",
pc->data[i].name,
pc->data[i].age,
pc->data[i].sex,
pc->data[i].tel,
pc->data[i].addr);
}
void ModifityContact(Contact* pc)
{
char name[NAME] = { 0 };
printf("亲输入要修改人的姓名->");
scanf("%s", name);
int ret = FindByName(pc, name);
if (ret == -1)
{
printf("查无此人->");
return;
}
printf("修改开始->\n");
printf("亲输入姓名->");
scanf("%s", pc->data[ret].name);
printf("亲输入年龄->");
scanf("%d", &(pc->data[ret].age));
printf("亲输入性别->");
scanf("%s", pc->data[ret].sex);
printf("亲输入电话号->");
scanf("%s", pc->data[ret].tel);
printf("亲输入地址->");
scanf("%s", pc->data[ret].addr);
printf("修改成功\n");
}