目录

通讯录基本要求:

实现功能:

一、打印菜单:

二、联系人信息存储

三、通讯录初始化及功能:

1、静态存储通讯录

(1)、通讯录信息:

(2)、初始化通讯录:

(3)、通讯录功能:

2、动态存储通讯录

(1)、通讯录信息:

(2)、初始化通讯录:

(3)、通讯录功能:

四、通讯录主函数:


通讯录基本要求:

​​​​​​​        ​​​​​​​     存储人数:100

人员信息: 姓名、性别、年龄、电话、住址

实现功能:

                        添加联系人信息

                        删除联系人信息

                        查找联系人信息

                        修改联系人信息

                        显示联系人信息

                        按名字排序所有联系人

一、打印菜单:

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");
}

二、联系人信息存储

先定义一个peoinfo的结构体
,用来存放联系人的基本信息,成员包括name、sex、tele、age、addr。

//联系人信息:
struct peoinfo
{char name[MAX_NAME];char sex[MAX_SEX];char tele[MAX_TELE];int age;char addr[MAX_ADDR];};

三、通讯录初始化及功能:

1、静态存储通讯录

(1)、通讯录信息:

然后再定义一个contact的结构体,里面用来存放结构体peoinfo 和通讯录内联系人的个数sz。

struct contact
{struct peoinfo data[MAX];int sz;
};

(2)、初始化通讯录:

void initcontact(struct contact* pc)
{assert(pc);pc->sz = 0;memset(pc->data, 0, MAX * sizeof(struct peoinfo));
}

初始化时先断言是否为空。然后分开初始化,利用结构体的访问形式pc->sz = 0,对于数组,我们利用内存设置函数memset来初始化,以字节为单位一个字节一个字节的初始化!

(3)、通讯录功能:

        1.添加联系人

在添加新的联系人时,首先断言是否为空;然后要看通信录是否还有空间,进行通讯录是否为满判断,若没有空间则结束进程,若有空间则输入个人的信息存储到数组里;添加完成后sz++

void addcontact(struct contact* pc)
{assert(pc);if (pc->sz==MAX){printf("通讯录已满,无法添加数据!!!\n");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");
}

        2.删除联系人

删除联系人之前先进行按姓名的人员查找,包括下面的查找联系人、修改联系人都需要用到这个查找,所以我们就不妨封装一个函数——遍历整个数组通过名字来进行查找,找到就返回下标,找不到返回-1;

通过查找函数先判断通讯里面是否存在人员,不存在就不需要操作,结束进程;若存在则删除表中人员的信息——只需要把ret后的数据依次往前移动,覆盖掉前一个位置的信息就可以了。删除成功后把sz--。

int findname(const struct contact* pc, char name[])
{for (int i = 0; i < pc->sz; i++)if (0 == strcmp(pc->data[i].name, name))return i;return -1;
}
void delecontact(struct contact* pc)
{char name[MAX_NAME];printf("请输入要删除的联系人姓名:");scanf("%s", name);int ret = findname(pc, name);if (ret == -1)printf("不存在!!!\n");else{pc->data[ret] = pc->data[pc->sz];pc->sz--;printf("删除成功\n");}
}

        3.查找联系人

运用之前的查找函数根据姓名进行查找,若返回-1则找不到结束进程;若找到了,根据返回的ret下标,打印信息即可!

void searchcontact(const struct contact* pc)
{char name[MAX_NAME];printf("输入要查找的人姓名:");scanf("%s", name);int ret = findname(pc, name);if (ret == -1)printf("要查找的人不存在!\n");else{printf("%-20s\t%-5s\t%-5s\t%-12s\t%-30s\n", "姓名","性别", "年龄", "电话", "地址");printf("%-20s\t%-5s\t%-5d\t%-12s\t%-30s\n", pc->data[ret].name,pc->data[ret].sex,pc->data[ret].age,pc->data[ret].tele,pc->data[ret].addr);}
}

        4.展示联系人

首先先打印一个标题,增加可读性!然后在利用for循环打印信息。默认是左对齐的、负号代表右对齐。所以在这里为了美观性我们可以用负号进行右对齐

void showcontact(const struct contact* pc)
{printf("%-20s\t%-5s\t%-5s\t%-12s\t%-30s\n", "姓名", "性别", "年龄", "电话", "地址");for (int i = 0; i < pc->sz; i++){printf("%-20s\t%-5s\t%-5d\t%-12s\t%-30s\n", pc->data[i].name,pc->data[i].sex,pc->data[i].age,pc->data[i].tele,pc->data[i].addr);}
}

        5.修改联系人

通过查找函数根据姓名进行查找,找不到就返回-1结束进程;找到了则根据返回的下标ret,再次输入信息覆盖之前的信息。

void modifycontact(struct contact* pc)
{printf("请输入要修改的人的姓名:");char name[MAX_NAME];scanf("%s", name);int ret = findname(pc, name);if (ret == -1)printf("要修改的人不存在!!!\n");else{printf("输入姓名:");scanf("%s", pc->data[ret].name);printf("输入性别:");scanf("%s", pc->data[ret].sex);printf("输入年龄:");scanf("%d", &(pc->data[ret].age));printf("输入电话:");scanf("%s", pc->data[ret].tele);printf("输入地址:");scanf("%s", pc->data[ret].addr);printf("修改成功!!!");}
}

        6.按照联系人姓名排序

在这里我们可以运用 qsort() 函数进行排序!

int cmpname(const void* p1, const void* p2)
{return(strcmp(((struct peoinfo*)p1)->name, ((struct peoinfo*)p2)->name));
}
void sortcontact(struct contact* pc)
{qsort(pc->data, pc->sz, sizeof(struct peoinfo), cmpname);
}

 注:这个通讯录我们采用静态存储的模式即顺序表的方式来实现,但是静态存储的通讯录对于内存的利用不是很有效,存在着一些明显的弊端,当存储人数少时,存在空间浪费现象;当人数达到设置值时便不能再进行存储,存在空间不足的现象。因此下面的动态存储通讯录便是基于此的优化! 

2、动态存储通讯录

(1)、通讯录信息:

相比于静态存储,这里可以利用指针动态创建内存,此外还增加了一个变量来记录当前内存的容量

struct contact
{struct peoinfo *data; //指向了存放数据的空间int sz;               //已经放进去的信息int capacity;         //容量
};

(2)、初始化通讯录:

void initcontact(struct contact* pc)
{assert(pc);pc->data = (struct peoinfo*)malloc(DEFAULT_SZ * sizeof(struct peoinfo));if (pc->data == NULL){perror("initcontact");return;}pc->sz = 0;pc->capacity = DEFAULT_SZ;
}

(3)、通讯录功能:

        1.添加联系人

static int check_capacity(struct contact* pc)
{if (pc->sz == pc->capacity){//增加容量struct peoinfo* ptr = realloc(pc->data, (pc->capacity + INC_SZ) * sizeof(struct peoinfo));if (ptr != NULL){pc->data = ptr;pc->capacity += INC_SZ;printf("增容成功!\n");return 1;}else{perror("addcontact");return 0;}}elsereturn 1;
}
void addcontact(struct contact* pc)
{assert(pc);if (0 == check_capacity(pc)){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");
}

        2.删除联系人

void delecontact(struct contact* pc)
{char name[MAX_NAME];printf("请输入要删除的联系人姓名:");scanf("%s", name);int ret = findname(pc, name);if (ret == -1)printf("不存在!!!\n");else{for (int j = ret; j < pc->sz - 1; j++){pc->data[j] = pc->data[j + 1];}pc->sz--;printf("成功删除指定联系人\n");}
}

        3.查找联系人

void searchcontact(const struct contact* pc)
{char name[MAX_NAME];printf("输入要查找的人姓名:");scanf("%s", name);int ret = findname(pc, name);if (ret == -1)printf("要查找的人不存在!\n");else{printf("%-20s\t%-5s\t%-5s\t%-12s\t%-30s\n", "姓名", "性别", "年龄", "电话", "地址");printf("%-20s\t%-5s\t%-5d\t%-12s\t%-30s\n", pc->data[ret].name,pc->data[ret].sex,pc->data[ret].age,pc->data[ret].tele,pc->data[ret].addr);}
}

        4.展示联系人

void showcontact(const struct contact* pc)
{printf("%-20s\t%-5s\t%-5s\t%-12s\t%-30s\n", "姓名", "性别", "年龄", "电话", "地址");for (int i = 0; i < pc->sz; i++){printf("%-20s\t%-5s\t%-5d\t%-12s\t%-30s\n", pc->data[i].name,pc->data[i].sex,pc->data[i].age,pc->data[i].tele,pc->data[i].addr);}
}

        5.修改联系人

void modifycontact(struct contact* pc)
{printf("请输入要修改的人的姓名:");char name[MAX_NAME];scanf("%s", name);int ret = findname(pc, name);if (ret == -1)printf("要修改的人不存在!!!\n");else{printf("输入姓名:");scanf("%s", pc->data[ret].name);printf("输入性别:");scanf("%s", pc->data[ret].sex);printf("输入年龄:");scanf("%d", &(pc->data[ret].age));printf("输入电话:");scanf("%s", pc->data[ret].tele);printf("输入地址:");scanf("%s", pc->data[ret].addr);printf("修改成功!!!");}
}

        6.按照联系人姓名排序

int cmpname(const void* p1, const void* p2)
{return(strcmp(((struct peoinfo*)p1)->name, ((struct peoinfo*)p2)->name));
}
//按照姓名来排序
void sortcontact(struct contact* pc)
{qsort(pc->data, pc->sz, sizeof(struct peoinfo), cmpname);
}

        7.销毁通讯录 

释放pc->data指针,并手动置为NULL,把sz和capacity置为0

销毁通讯录可以不写在菜单里,直接写到退出通讯录里面,当退出时直接调用这个销毁函数。

void destroycontact(struct contact* pc)
{free(pc->data);pc->data = NULL;pc->capacity = 0;pc->sz = 0;
}

四、通讯录主函数:

int main()
{int input = 0;struct contact con;//初始化initcontact(&con);do{menu();printf("输入选择:");scanf("%d", &input);switch (input){case 1:addcontact(&con);break;case 2:delecontact(&con);break;case 3:searchcontact(&con);break;case 4:modifycontact(&con);break;case 5:showcontact(&con);break;case 6:sortcontact(&con);break;case 0://destroycontact(&con);    //动态存储时使用printf("退出");break;default:printf("输入错误");break;}} while (input);return 0;
}

C语言题目——通讯录(静态存储+动态存储)相关推荐

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

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

  2. 通讯录最终版——动态存储+文件处理

    最终版通讯录即从上一个版本修改过来 先看总体代码,我们再看看差异 ps:里面涉及到很多函数的使用,后续我会出专栏来书写这些函数的使用和实例,与常见错误 大家可以通过https://cplusplus. ...

  3. C语言题目——通讯录2.0(可存档通讯录)

    目录 一.文件保存函数 二.文件导入函数 三.总代码 1.contact.h: 2.contact.c: 3.test_contact.c: 一.文件保存函数 此函数的功能就是将该通讯录里面的信息以二 ...

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

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

  5. c语言静态存储和动态存储,C语言中的静态内存与动态内存

    我们知道,内存分为动态内存和静态内存,我们先讲静态内存. 一.静态内存 内存管理---存储模型 存储模型决定了一个变量的内存分配方式和访问特性,在C语言中主要有三个维度来决定:1.存储时期 2.作用域 ...

  6. C语言—静态存储与动态存储

    静态存储和动态存储 变量从变量值存在的时间(即生存期)角度分:静态存储方式和动态存储方式 静态:在编译时确定了固定的内存地址与内存大小,如:函数里的局部变量.全局变量等 动态:由程序控制,运行时主动性 ...

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

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

  8. C中静态存储区和动态存储区

    c语言中需要内存来存放数据.而内存主要分为两类:静态存储区和动态存储区. 1.静态存储区 (1)分为数据区(只读数据区(代码区?在linux中又叫文本段.text).读写数据区.data).未初始化区 ...

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

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

最新文章

  1. 如何在ASP.Net 中把图片存入数据库
  2. json / 简介及结构
  3. scikit-learn 逻辑回归类库使用小结
  4. linux6.5进入救援模式,rhel6.5救援模式修复系统
  5. Koa 中实现 chunked 数据传输
  6. solaris10默认防火墙软件ipfilter
  7. 卸载抖音,迎接一大波正在路上的“抖音”!
  8. jprofiler 9注册码
  9. Vue中无法更改element ui组件样式问题
  10. 受宠的背后:安全市场面临重新洗牌
  11. 谭浩翔c语言,严谨细致的科技尖兵丨广州市公安局黄埔区分局民警谭浩翔
  12. 物联网协议之一:MQTT协议和kafka
  13. CL-ReLKT: Cross-lingual Language Knowledge Transfer for MultilingualRetrieval Question Answering论文阅读
  14. 广义表与二叉树之间的相互转换
  15. 解决迅雷敏感资源无法下载问题
  16. Windows下编译FFmpeg 32位和64位DLL
  17. 反射(reflect)应用详解
  18. FS00 创建科目 GL_ACCT_MASTER_SAVE
  19. 详解printf重定向到文件中,打印日志的实现
  20. linux添加组管理员,centos下添加管理员组和添加管理员用户及相关操做

热门文章

  1. 完整!贪吃蛇游戏c语言代码分享(包括界面,计数,提示)
  2. 工作两年,Java社招岗位,阿里,头条等多家大厂面经出炉
  3. 2021/11/16 定时器Timer和cron表达式
  4. 怎么在navicat(Navicat for MySQL)中运行SQL代码
  5. C++黑客攻击系统-重复验证
  6. minmea——GPS NMEA 0183 协议解析库
  7. mysql coreseek_Linux下PHP+MySQL+CoreSeek中文检索引擎配置
  8. C Primer Plus学习_8第四章编程练习(略带解释 )
  9. java 之文件输入输出流
  10. QT的中文显示乱码问题解决