当前使用VS2019编译器

首先建立2个源文件test.c和contect.c以及1个头文件contect.h

一.通讯录操作菜单

void menu()
{printf("********  1.Add     2.Del    ***********************\n");printf("********  3.Search  4.Modify ***********************\n");printf("********  5.Sort    6.Print  ***********************\n");printf("********  7.Destroy 0.Exit   ***********************\n");printf("****************************************************\n");
}

1. 定义结构体变量以及枚举常量

typedef struct PeoInfo//该结构体变量用来存储个人的信息
{char name[NAME_MAX];//以下数组中的值为#define的宏定义char sex[SEX_MAX];int age;char tele[TELE_MAX];char addr[ADDR_MAX];
}PeoInfo;
typedef struct Contect//静态版本
{PeoInfo data[MAX];//用来储存MAX个PeoInfo类型的数据int sz;//用来记录当前通讯录人数的个数
}Contect;//重命名
typedef struct Contect//动态版本
{PeoInfo* data;int sz;int capacity;
}Contect;
enum Select {//该枚举常量为通讯录菜单中的选择EXIT,ADD,DEL,SEARCH,MODIFY,SORT,PRINT,DESTROY
};
enum Modify {//该枚举常量为通讯录中修改函数中菜单的选择NAME=1,SEX,AGE,TELE,ADDR
};

2.选择操作

void test()
{int input = 0;Contect con;//定义一个Contect类型的变量InitContect(&con);//初始化do {menu();printf("请选择:>\n");scanf("%d", &input);switch (input)//下面的case语句中的常量为枚举常量{case ADD:AddContect(&con);break;case DEL:DelContect(&con);break;case SEARCH:SearchContect(&con);break;case MODIFY:ModifyContect(&con);break;case SORT:SortContect(&con);break;case PRINT:PrintContect(&con);break;case DESTROY:DestroyContect(&con);break;case EXIT:printf("退出程序");break;default:printf("选择错误");break;}} while (input);
}

二.函数的声明

//初始化
void InitContect(Contect* pc);
//增加内容
void AddContect(Contect* pc);
//打印
void PrintContect(Contect* pc);
//删除内容
void DelContect(Contect* pc);
//查找内容
void SearchContect(const Contect* pc);
//修改内容
void ModifyContect(Contect* pc);
//排序内容
void SortContect(Contect* pc);
//销毁
void DestroyContect(Contect* pc);

三.函数的定义

1.通讯录的初始化

//静态版本
void InitContect(Contect* pc)
{assert(pc);//判断是否为NULLmemset(pc->data, 0, sizeof(pc->data));pc->sz = 0;
}

memset的作用是将缓冲区设置为指定的字符'0'

//动态版本
void InitContect(Contect* pc)
{assert(pc);pc->sz = 0;pc->capacity = DEFAULT_SZ;//设置初始化能存DEFAULT_SZ个数据,其中DEFAULT_SZ为宏定义的内容pc->data = (PeoInfo*)malloc(pc->capacity * sizeof(PeoInfo));//用malloc动态分配内存给data数组if (pc->data==NULL){perror("InitContect::malloc");//显示动态分配内存出错的信息return;}memset(pc->data, 0, pc->capacity * sizeof(PeoInfo));
}

malloc用来分配内存,单位为字节

2.通讯录内容的添加

void AddContect(Contect* pc)
{assert(pc);//静态版本if (pc->sz == MAX){printf("通讯录已满,无法添加");return;}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].tele);printf("请输入地址:");scanf("%s", pc->data[pc->sz].addr);pc->sz++;printf("添加成功\n");
}
void AddContect(Contect* pc)
{assert(pc);//动态版本CheckCapacity(pc);//该函数用来判断当前通讯录能够存储的内容是否达到最大值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].tele);printf("请输入地址:");scanf("%s", pc->data[pc->sz].addr);pc->sz++;printf("添加成功\n");
}
void CheckCapacity(Contect* pc)
{assert(pc);if (pc->sz == pc->capacity)//sz为当前通讯录中数据的个数,capacity为当前通讯录中最多能存储数据的个数{PeoInfo* tmp = (PeoInfo*)realloc(pc->data, (pc->capacity + 2) * sizeof(PeoInfo));//每次增加2个存储数据的空间if (tmp != NULL){pc->data = tmp;//tmp不等于空指针说明内存分配成功,将成功分配的内存给data数组}else{perror("CheckCapacity::realloc");//内存分配失败的原因return;}pc->capacity += 2;printf("增容成功\n");}
}

realloc 的作用为重新分配内存块,能增能减

3.通讯录内容的删除

void DelContect(Contect* pc)
{assert(pc);char name[NAME_MAX] = { 0 };printf("请输入要删除的姓名:");scanf("%s", name);int ret = Search_by_name(pc, name);//找到想要删除的对象if (-1 == ret){printf("无法找到该内容\n");return;}for (int i = ret; i < pc->sz - 1; i++)//将删除对象后面的数据往前移{pc->data[i] = pc->data[i + 1];}pc->sz--;printf("删除成功\n");
}

3.通讯录内容的查找

void SearchContect(const Contect* pc)
{assert(pc);char name[NAME_MAX] = { 0 };printf("请输入要查找的姓名:");scanf("%s", name);int pos = Search_by_name(pc, name);//通过名字查找if (-1 == pos){printf("无法找到该内容\n");}else{printf("%-20s %-5s %-5s %-12s %-30s\n", "姓名", "年龄", "性别", "电话", "地址");printf("%-20s %-5d %-5s %-12s %-30s\n", pc->data[pos].name, pc->data[pos].age, pc->data[pos].sex, pc->data[pos].tele, pc->data[pos].addr);}
}
int Search_by_name(Contect* pc, char name[])
{assert(pc);for (int i = 0; i < pc->sz; i++){if (0 == strcmp(name, pc->data[i].name))//strcmp为字符串的比较,不懂的详见上一篇{return i;}}return -1;
}

4.通讯录内容的修改

修改菜单:

void MENU()
{printf("********** 1.name  2.sex  **********\n");printf("********** 3.age   4.tele **********\n");printf("********** 5.addr  0.exit **********\n");
}
void ModifyContect(Contect* pc)
{assert(pc);char name[NAME_MAX] = { 0 };printf("请输入要修改的人的姓名:");scanf("%s", name);int ret = Search_by_name(pc, name);//找到要修改的对象if (-1 == ret){printf("无法找到要修改的人的信息\n");return;}int input = 0;do {MENU();printf("请选择要修改的内容:");scanf("%d", &input);switch (input){case NAME:printf("请输入名字:");scanf("%s", pc->data[ret].name);printf("修改成功\n");break;case SEX:printf("请输入性别:");scanf("%s", pc->data[ret].sex);printf("修改成功\n");break;case AGE:printf("请输入年龄:");scanf("%d", &(pc->data[ret].age));printf("修改成功\n");break;case TELE:printf("请输入电话:");scanf("%s", pc->data[ret].tele);printf("修改成功\n");break;case ADDR:printf("请输入地址:");scanf("%s", pc->data[ret].addr);printf("修改成功\n");break;case EXIT:printf("退出修改程序\n");break;default:printf("输入错误\n");break;}} while (input);
}

5.通讯录的排序(以名字排序)

void SortContect(Contect* pc)
{assert(pc);qsort(pc->data, pc->sz, sizeof(PeoInfo), compare);//使用qsort库函数进行排序printf("排序成功\n");
}

该函数最后一个参数内容为自定义函数,以要通过什么内容来进行排序编写函数

int compare(const void* e1, const void* e2)
{return strcmp(((struct PeoInfo*)e1)->name, ((struct PeoInfo*)e2)->name);
}

6.通讯录的打印

void PrintContect(Contect* pc)
{assert(pc);if (0 == pc->sz){printf("通讯录中无内容\n");}elseprintf("%-20s %-5s %-5s %-12s %-30s\n", "姓名", "年龄", "性别", "电话", "地址");for (int i = 0; i < pc->sz; i++){printf("%-20s %-5d %-5s %-12s %-30s\n", pc->data[i].name, pc->data[i].age, pc->data[i].sex, pc->data[i].tele, pc->data[i].addr);}
}

7.通讯录的销毁

void DestroyContect(Contect* pc)
{free(pc->data);/需要通过free函数来进行释放动态分配的内存空间否则会导致内存泄露pc->sz = 0;pc->capacity = 0;pc->data = NULL;printf("销毁成功\n");
}

C语言实现通讯录(静态版本+动态版本)相关推荐

  1. 从0开始学c语言 - 34 - 通讯录 -静态、动态、存到文件(三种版本)

    上一篇:从0开始学c语言-33-动态内存管理_阿秋的阿秋不是阿秋的博客-CSDN博客 我发现,理论的学习文章没几个人看,如果是这种实践类型的文章,看的人很多,偏偏我之前都是扔完代码就走了,也没认真写这 ...

  2. linux c语言静态库,linux下的C语言开发(静态库/动态库)

    今天我们讨论的问题是静态库.为了显示windows和Linux创建静态库之间的差别,我们首先在windows上面利用Visual C++6.0创建一个静态库.源文件的代码很简单, #include & ...

  3. 通讯录的实现(静态版本,动态版本,文件版本)(后附完整源代码)

    通讯录的实现 一.静态版本 1.所需要的功能 2.大致菜单 3.创建通讯录 4.增加联系人 5.显示联系人 6.查找联系人 7.删除联系人 8.修改联系人 9.按名字排序 10.源代码 二.动态版本 ...

  4. C语言实现通讯录【二】(动态内存开辟,文件数据存储)

    C语言实现通讯录[二] 在C语言实现通讯录[一]的基础上进行优化,主要实现两大模块: 动态内存开辟 文件数据存储 动态内存开辟: 考虑到通讯录的大小无法固定,在C语言实现通讯录[一]版本上定义一个足够 ...

  5. [C语言] 通讯录|静态 动态 文件 链表 多版本讲解

    学校的期末小作业,相当于对我们本学期所学内容的一个总结.只要对标题所指内容有所了解即可轻松读懂本题解.下面我们按照要求一步步由浅入深地解决这个问题. 目录 ​ 静态版本 定义类型 添加 输出 查找 修 ...

  6. 通讯录(动态版本)--C语言

    目录 前言 程序设计 1. 通讯录的创建 2. 初始化通讯录 3. 动态增加容量 4. 销毁通讯录 前言 前面已经讲述了静态版本的通讯录,为了能够有更友好的使用通讯录,这次我将讲述以下如何将静态版本的 ...

  7. 简陋版C语言仿真通讯录之动态内存开辟版本

    简陋版C语言仿真通讯录 https://blog.csdn.net/csdn_kou/article/details/80287640 简陋版C语言仿真通讯录之动态内存开辟版本 给Contact结构体 ...

  8. C语言课设作业《通讯录》全程记录 ps:动态版本

    写在前面: 通讯录算是前面对学过知识的一个综合运用,涉及到的知识点有 :枚举类型,结构体.结构体指针.动态内存分配(malloc,calloc,realloc,free).typedef关键字.多文件 ...

  9. C语言小项目 -- 通讯录(静态版+动态版+文件版)

    文章目录 一.总体设计思路 1.设计背景 2.设计框架 3.功能概述 二.通讯录(静态版) 1.结构体设计 2.初始化通讯录 3.添加联系人信息 4.删除联系人信息 5.查找联系人(按姓名) 6.查找 ...

最新文章

  1. Linux下addr2line命令用法
  2. SSH pager-taglib分页的实现
  3. 分享自己整理的《UIT备份容灾解决方案培训稿》
  4. JVM PrintGCDetails打印GC细节
  5. java去除字符串的html标签
  6. 深度学习(七十三)pytorch学习笔记
  7. java中如何播放背景mp3音乐_java播放背景音乐
  8. python中的math.floor可以用于整数吗_为什么Python的math.ceil()和math.floor()操作返回浮点数而不是整数?...
  9. Android USB打印机
  10. 手机上最好用的五笔输入法_最欠揍的手机输入法,用不好失业又失恋
  11. 尊重钟南山,但请也给我们哀悼科比
  12. 【计算机毕业设计】017学生公寓电费信息管理系统
  13. 英特尔第十代处理器为什么不支持win7_Intel 第十代CPU(部分U)装WIN7
  14. 基于Web SCADA平台构建数字化车间的MES系统
  15. airpods麦克风测试软件,苹果AirPods新维修工具上线:可区分是污垢堵塞还是故障...
  16. 线性代数系列(十一)--正交矩阵和正交化
  17. appinventor连接MySQL_appinventor如何连接sqlserver数据库
  18. 基于Multisim的自动售货的电路课程设计
  19. 【系统分析师之路】面向对象开发方法,Coad方法、Booch方法和OMT方法及UML
  20. 对高校一线教师开展翻转课堂的建议

热门文章

  1. 标准盒子模型和怪异盒子模型(详解)
  2. PYTHON使用arcpy出现“Error 000824: The tool is not licensed”
  3. 康拓排列的自我总结--以及全排列的递归非递归算法
  4. 竞赛冠军方案:2020珠港澳人工智能算法大赛双料冠军解读
  5. 参考霍兰德人格分析雷达图的思路来设计一组学生八门课的成绩雷达图
  6. SQL INSERT 语句
  7. 工程师解密:实例分析数控机床故障及排除
  8. Intellij Idea:禁忌,请勿手残
  9. 查看U盘占用程序的方法
  10. VUE组件之数据共享