目录
一:前言
在前面写过一篇关于通讯录的实现,不少朋友问得最多的问题就是如果想对通讯录排序的话
1:应该怎么样排序。
2:如果退出怎么才能保存现在已经录入的人员信息,
3:用动态内存来实现我需要一个人员信息开辟一个空间。
如果有不明白的可以看看我前面写的关于通讯录的一些基本实现
跳转地址:
https://blog.csdn.net/Trustmeican/article/details/126264716?spm=1001.2014.3001.5501
接下来我们进入正题。
二:对通讯录排序
排序我们可以有很多种,可以按照年龄排序,也可以按照名字或者其他的一些进行排序,接下来这里我们按照名字排序。排序其实也很简单,C语言中有一个函数专门准备出来用于排序的。那这里我们就可以运用到这个函数,qsort有四个参数,第一个是传入排序的那个起始地址,第二个是需要排序的元素个数,第三个是排序的的大小,单位为字节,第四个就是比较函数,无论你是要按照什么方式排序,我们只需要传入这四个参数,qsort会自己帮我们搞定排序的问题,或者说你也可以自己去实现对内容的排序,前面我也写过,感兴趣的话可以去看一看。
跳转地址:
https://blog.csdn.net/Trustmeican/article/details/125690956?spm=1001.2014.3001.5501
三:动态内存开辟
我们在写这个通讯录的时候,如果一上来就开辟一大块空间,但是我们又用不到这么多空间的话就会造成很严重的空间浪费,但是我们一开始只开辟能容纳三个人的空间,到后面没增加几个人我们就开辟几个空间就很很大程度上的减少空间的浪费。过程也很简单,我们只需要在每次增加人数的时候进行一次判断,如果通讯录里面的人满了就进行增容,满了就增容就可以完成了。
四:对通讯录的人进行保存
这里会涉及到我们的文件操作,我们在通讯录里面新增一个选项,当我们选择保存的时候,当前已有的联系人就能保存到我们的通讯录里面。怎么实现这个操作呢。我们可以用文件操作中的fread和fwrite来完成,只需要写上一个循环,把当前通讯录的人一次一次的添加到我们的文本文件里面,在下一次启动这个程序的时候先让程序去读取文本里面的内容,这样我们下次启动程序的时候就能显示当前已有的联系人信息了。
五:实现代码
//测试
#include"Cont.h"
void menu()
{
printf("***************************\n");
printf("*******1:增加 2:删除*****\n");
printf("*******3:修改 4:查找*****\n");
printf("*******5:排序 6:显示*****\n");
printf("*******7:保存 0:退出*****\n");
printf("***************************\n");
printf("***************************\n");
}
int main()
{
int input = 0;
//初始化
InitPeo(&con);
do
{
menu();
printf("请选择:>");
scanf("%d", &input);
switch (input)
{
case 1:
AddContact(&con);
break;
case 2:
DelContact(&con);
break;
case 3:
ModF(&con);
break;
case 4:
Find(&con);
break;
case 5:
Sort(&con);
break;
case 6:
Print(&con);
break;
case 7:
SeveContact(&con);
DispContact(&con);
break;
case 0:
printf("退出程序\n");
break;
default:
printf("请输入0-7的数字\n");
}
} while (input);
return 0;
}
//需要的头文件
#pragma once
#define _CRT_SECURE_NO_WARNINGS 1
#define FILE_BUFFER_LENGTH 30000
#include<stdio.h>
#include<stdlib.h>
#include<windows.h>
#include<string.h>
#include<math.h>
#include<time.h>
#include<assert.h>
#define Max_n 20
#define Max_s 5
#define Max_a 10
#define Max_t 12
#define Defalut_sz 3
#define INC_sz 2
typedef struct PeoInfo
{
char name[Max_n];
int age;
char sex[Max_s];
char addr[Max_a];
char tele[Max_t];
}PeoInfo;
PeoInfo* data;
typedef struct Contact
{
PeoInfo* data;
int sz;
int capatity;
}Contact;
Contact con;
//初始化通讯录
void InitPeo(Contact* pc);
//添加联系人
void AddContact(Contact* pc);
//删除联系人
void DelContact(Contact* pc);
//显示当前通讯录联系人
void Print(const Contact* pc);
//查找联系人
void ModF(Contact* pc);
void Find(const Contact* pc);
//对联系人进行排序
void Sort(Contact* pc);
//保存当前通讯录的联系人
void SeveContact(Contact* pc);
//销毁通讯录
void DispContact(Contact* pc);
//通讯录实现的内容
#include"Cont.h"
//开辟空间
void cheack_capatity(Contact* pc)
{
if (pc->sz == pc->capatity)
{
PeoInfo* ptr = (PeoInfo*)realloc(pc->data, (pc->capatity + INC_sz) * sizeof(PeoInfo));
if (ptr == NULL)
{
perror("realloc:");
return;
}
pc->data = ptr;
pc->capatity += INC_sz;
printf("开辟成功\n");
}
}
//读取文本内容
void LoadContact(Contact* pc)
{
int count = 0;
PeoInfo tmp = { 0 };
FILE* pf = fopen("contact.txt", "rb");
if (pf == NULL)
{
perror("LoadContact:"); //如果文件指针开辟失败打印失败原因
return;
}
int i = 0;
while (fread(&tmp, sizeof(PeoInfo), 1, pf)) //拿一个ProInfo类型的变量来接受文本内容
{
cheack_capatity(pc); //判断一下当前通讯录是否满了
pc->data[i] = tmp; //把每一次从文本里面拿出来的人员信息放入data里面
i++;
pc->sz++; //没放一次之后通讯录的人就需要增加一个
count++;
}
fclose(pf);
}
//初始化通讯录
void InitPeo(Contact* pc)
{
PeoInfo* ptr = (PeoInfo*)calloc(Defalut_sz, sizeof(PeoInfo)); //动态开辟
if (ptr == NULL)
{
perror("calloc:"); //开辟失败打印失败原因
return;
}
pc->data = ptr; //开辟成功吧开辟好的空间给data
pc->capatity += Defalut_sz; //当前通讯录的空间为3
LoadContact(pc); //加载文本里面是否有上次保存的联系人
}
int FindByName(Contact* pc, char name[])
{
assert(pc);
scanf("%s", name);
for (int i = 0; i < pc->sz; i++)
{
if (strcmp(pc->data[i].name, name) == 0)
return i;
}
return -1;
}
//显示联系人
void Print(const Contact* pc)
{
printf("%s%20s%20s%20s%20s\n", "姓名", "年龄", "性别", "地址", "电话");
for (int i = 0; i < pc->sz; i++)
{
printf("%s%20d%20s%20s%20s\n", pc->data[i].name,
pc->data[i].age,
pc->data[i].sex,
pc->data[i].addr,
pc->data[i].tele);
}
}
//添加联系人
void AddContact(Contact* pc)
{
cheack_capatity(pc);
printf("请输入\n%s%20s%20s%20s%20s\n", "姓名", "年龄", "性别", "地址", "电话");
scanf("%s", pc->data[pc->sz].name);
scanf("%d", &pc->data[pc->sz].age);
scanf("%s", pc->data[pc->sz].sex);
scanf("%s", pc->data[pc->sz].addr);
scanf("%s", pc->data[pc->sz].tele);
pc->sz++;
}
//删除联系人
void DelContact(Contact* pc)
{
printf("请输入需要删除的姓名;>\n");
char name[20] = { 0 };
int ret = FindByName(pc, name);
if (ret == -1)
return;
for (int i = ret; i < pc->sz - 1; i++)
{
pc->data[i] = pc->data[i + 1];
}
pc->sz--;
printf("删除成功\n");
Print(&con);
}
//修改联系人
void ModF(Contact* pc)
{
printf("请输入需要修改人的姓名:>\n");
char name[20] = { 0 };
int ret = FindByName(pc, name);
if (ret == -1)
{
printf("需要修改人不存在\n");
return;
}
printf("请输入修改人的姓名:年龄:性别:地址:电话\n");
scanf("%s", pc->data[ret].name);
scanf("%d", &pc->data[ret].age);
scanf("%s", pc->data[ret].sex);
scanf("%s", pc->data[ret].addr);
scanf("%s", pc->data[ret].tele);
printf("修改成功\n");
Print(&con);
}
//查找联系人
void Find(const Contact* pc)
{
printf("请输入查找人的姓名\n");
char name[20] = { 0 };
int ret = FindByName(pc, name);
if (ret == -1)
{
printf("此联系人不存在\n");
return;
}
printf("%s%20d%20s%20s%20s\n", pc->data[ret].name,
pc->data[ret].age,
pc->data[ret].sex,
pc->data[ret].addr,
pc->data[ret].tele);
}
//自定义对联系人按名称排序
int cmp(const void* e1, const void* e2)
{
return strcmp(((PeoInfo*)e1)->name, ((PeoInfo*)e2)->name);
}
//void Swap(char* dest, char* src, size_t width)
//{
// for (int i = 0; i < width; i++)
// {
// char tmp = *dest;
// *dest = *src;
// *src = tmp;
// }
//}
//void MyBubbleSort(void* dest, size_t sz, size_t width, int (*cmp)(const void* e1, const void* e2))
//{
// for (int i = 0; i < sz - 1; i++)
// {
// for (int j = 0; j < sz - 1 - i; j++)
// {
// if (cmp((char*)dest + j * width, (char*)dest + (j + 1) * width) > 0)
// {
// Swap((char*)dest + j * width, (char*)dest + (j + 1) * width, width);
// }
// }
// }
//}
void Sort(Contact* pc)
{
//MyBubbleSort(pc->data, pc->sz, sizeof(PeoInfo), cmp);
qsort(pc->data, pc->sz, sizeof(PeoInfo), cmp);
Print(&con);
}
//保存联系人
void SeveContact(Contact* pc)
{
FILE* pf = fopen("contact.txt", "wb"); //开辟一个文件指针以二进制的形式打开
if (pf == NULL)
{
perror("SeveContact:"); //失败打印失败原因
return;
}
int i = 0;
for (i = 0; i < pc->sz; i++)
{
fwrite(&pc->data[i], sizeof(PeoInfo), 1, pf); //把当前通讯录人员里面的信息内容保存在文本中
}
printf("写入成功\n");
fclose(pf);
}
//销毁通讯录
void DispContact(Contact* pc)
{
free(pc->data);
pc->data = NULL;
pc->sz = 0;
pc->capatity = 0;
pc = NULL;
}