1.头文件
#pragma once
#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <string.h>
//#define MAX 100
#define MUL 2
void menu();
typedef struct people {
char name[20];
int age;
char sex[10];
char tele[12];
char addr[30];//地址
}peo;
//typedef struct Contact {
// peo data[MAX];
// int count;(静态的版本)
//}Con;
//动态的版本
typedef struct Contact {
peo *data;
int count;
int capacity;
}Con;
void InitContact(Con* con);//初始化通讯录
void AddContact(Con* con);//增加通讯录中的用户
void ShowContact(const Con* con);//展示通讯录中的用户
void DeLContact(Con* con);//删除通讯录中的用户
void SearchContact(Con* con);//查找通讯录中的用户信息
void SortContact(Con* con);//按照年龄对用户的信息进行排序
void ModifyContact(Con* con);//对想要修改的对象内容进行修改
void Reclaim(Con* con);//对动态开辟的空间进行回收
2.头文件中函数声明对应的代码
#include "通讯录引用.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 7.Recliam**\n");
printf("****************************\n");
}
void InitContact(Con* con) {
assert(con);
con->count = 0;
//memset(con->data, 0, sizeof(con->data));//如果这里不用memset的话,那么因为和字符串一样的原因,
现在是一个地址,你不能再对他进行初始化,要用循环去做
con->capacity = 3;
con->data = (peo*)calloc(3,sizeof(peo));
if (con->data == NULL) {
printf("init处发生了错误:%s\n", strerror(errno));
}
}
void AddContact(Con* con) {
assert(con);
if (con->count ==con->capacity) {
printf("该通讯录已经满了,无法再进行加入用户,需要进行扩容\n");
peo* tmp = (peo*)realloc(con->data, (con->count * MUL)*sizeof(peo));
if (tmp == NULL) {
printf("在add处发生了错误:%s\n", strerror(errno));
}
else {
con->data = tmp;
con->capacity *= 2;
printf("成功扩容\n");
}
}
printf("请输入用户名字:\n");
scanf("%s", con->data[con->count].name);
printf("请输入年龄:\n");
scanf("%d", &(con->data[con->count].age));
printf("请输入性别\n");
scanf("%s", con->data[con->count].sex);
printf("请输入电话号码\n");
scanf("%s", con->data[con->count].tele);
con->count++;
printf("增加用户成功\n");
}
void ShowContact(const Con* con) {
assert(con!=NULL);
if (con->count == 0) {
printf("通讯录中暂时没有用户\n");
printf("通讯录用户数量%d/%d\n", con->count, con->capacity);
printf("展示完毕\n");
printf("---------------------------------------------------\n");
return;
}
int i = 0;
printf("接下来展示通讯录中的用户信息\n");
for (i = 0; i < con->count; i++) {
printf("用户%d.-------------\n",i+1);
printf("名字:%s\n", con->data[i].name);
printf("年龄:%d\n", con->data[i].age);
printf("性别:%s\n", con->data[i].sex);
printf("电话号码:%s\n", con->data[i].tele);
printf("--------------------------------\n");
}
printf("通讯录用户数量%d/%d\n", con->count, con->capacity);
printf("展示完毕\n");
printf("---------------------------------------------------\n");
}
static int FindContact(Con* con,char*findname) {//用static修饰之后只能在这.c中看见
if (con->count == 0) {
return 0;
}
int i = 0;
for (i = 0; i < con->count; i++) {
if (strcmp(con->data[i].name, findname)==0 ){
return i+1;//为了出去能过if语句,因为有i=0的情况
}
}
return 0;
}
void DeLContact(Con* con) {
assert(con);
char findname[20] = { 0 };
if (con->count == 0) {
printf("通讯录中并没有用户\n");
return;
}
printf("请输入你要删除的用户名字\n");
scanf("%s", findname);
int pos = FindContact(con,findname);//这里传进来的con已经是指针了,这是我的问题,变量名应该换的,记得不能用&
if (pos) {
printf("已找到该用户,正在进行删除\n");
int i = 0;
for (i = 0; i < con->count - 1; i++) {
con->data[i] = con->data[i + 1];
}
con->count--;
printf("删除完成\n");
}
else
printf("并没有找到该用户,无法进行删除\n");
}
void SearchContact(Con* con) {
assert(con);
char findname[20] = { 0 };
if (con->count == 0) {
printf("通讯录中并没有用户\n");
return;
}
printf("请输入你要查找的用户名字\n");
scanf("%s", findname);
int pos = FindContact(con, findname);//这里传进来的con已经是指针了,这是我的问题,变量名应该换的,记得不能用&
if (pos) {
printf("已找到该用户,下面是用户的信息展示\n");
printf("名字:%s\n", con->data[pos-1].name);
printf("年龄:%d\n", con->data[pos-1].age);
printf("性别:%s\n", con->data[pos-1].sex);
printf("电话号码:%s\n", con->data[pos-1].tele);
printf("--------------------------------\n");
}
else {
printf("并没有找到该用户\n");
}
}
int struct_int_cmp(const void* con1,const void *con2) {
return (((peo*)con1)->age - ((peo*)con2)->age);
}
int struct_char_cmp(const void* con1, const void* con2) {
return strcmp(((peo*)con1)->age ,((peo*)con2)->age);
}
void SortContact(Con* con) {
if (con->count == 0) {
printf("暂时还没有存入用户,无需排序\n");
return;
}
if (con->count == 1) {
printf("暂时只有1个用户,无需排序\n");
return;
}
int (*pf)(const void* con1,const void* con2) = struct_int_cmp;
qsort(con->data, con->count, sizeof(peo),pf);
printf("排序完成\n");
}
void ModifyContact(Con* con) {
assert(con);
char findname[20] = { 0 };
if (con->count == 0) {
printf("通讯录中并没有用户\n");
return;
}
printf("请输入你要修改的用户名字\n");
scanf("%s", findname);
int pos = FindContact(con, findname);//这里传进来的con已经是指针了,这是我的问题,变量名应该换的,记得不能用&
if (pos) {
printf("已找到该用户,下面是用户的信息展示\n");
printf("名字:%s\n", con->data[pos - 1].name);
printf("年龄:%d\n", con->data[pos - 1].age);
printf("性别:%s\n", con->data[pos - 1].sex);
printf("电话号码:%s\n", con->data[pos - 1].tele);
printf("--------------------------------\n");
printf("接下来请你输入想要修改的内容\n");
printf("请输入用户名字:\n");
scanf("%s", con->data[pos-1].name);
printf("请输入年龄:\n");
scanf("%d", &(con->data[pos-1].age));
printf("请输入性别\n");
scanf("%s", con->data[pos-1].sex);
printf("请输入电话号码\n");
scanf("%s", con->data[pos-1].tele);
printf("已经修改完毕\n");
}
else {
printf("并没有找到该用户\n");
}
}
void Reclaim(Con* con) {
free(con->data);
con->data = NULL;
InitContact(con);
printf("已经对动态开辟的空间进行回收\n");
}
3.主函数所在的.c文件
#include "通讯录引用.h"
int main() {
int input = 0;
Con con;
InitContact(&con);
do {
menu();
printf("请进行选择:\n");
scanf("%d", &input);
switch (input) {
case 1:
printf("正在进行add\n");
AddContact(&con);
break;
case 2:
printf("正在进行DeL\n");
DeLContact(&con);
break;
case 3:
printf("正在执行search\n");
SearchContact(&con);
break;
case 4:
printf("正在进行Modify\n");
ModifyContact(&con);
ShowContact(&con);
break;
case 5:
printf("正在进行展示\n");
ShowContact(&con);
break;
case 6:
printf("正在进行sort\n");
SortContact(&con);
ShowContact(&con);
break;
case 7:
printf("正在进行Reclaim\n");
Reclaim(&con);
break;
case 0:
printf("正在退出通讯录\n");
break;
default:
printf("你的输入存在错误,请重新进行输入\n");
scanf("%d", &input);
}
} while (input);
}
4.与上一篇文章差异之处的运行截图展示
(主要是在可以动态更新通讯录中可以存储用户的数量,采用的是两倍更新内存的方式进行处理;以及增加了对动态开辟空间内存的回收)