本期带大家一起来学习一下通讯录的三个版本(静态版+动态版+文件版)🌈🌈🌈
文章目录
-
- 一 、代码搭建:🎈
- 二 、代码思路:🎈🎈
- 三、代码实现🎈🎈🎈
-
- 1.框架搭建:🍊🍊
- 1.2 菜单函数打印信息交互🍊🍊
- 3:联系人创建 通讯录创建:🍊🍊
- 四、通讯录各种函数 实现:🍭🍭
-
- 1.初始化函数: 🥑 🥑 🥑
-
- 1.1 静态初始化 🥑 🥑
- 1.2 动态初始化 🥑 🥑
- 1.3 文件初始化 🥑 🥑
- 2. 添加联系人:🍭🍭
- 3.删除联系人:🍭🍭
- 5.查找联系人:🌰🌰
- 6. 显示联系人:🌰🌰
- 7.修改联系人:⚓️⚓️
- 8.按姓名对联系人进行排序:⚓️⚓️
- 9.退出通讯录⛱⛱⛱
-
- 9.1 静态版本 🚤 🚤
- 9.2 动态版本 🚤 🚤
- 9.3 文件版本 🚤 🚤 🚤
- 五、contact.h 头文件的声明🚀 🛸🚀 🛸
- 六、🚀 🛸源码分享(以文件版本为主)🚀 🛸
-
- ✈️1. contact.h 头文件✈️
- ✈️✈️2. contact.c 通讯录功能实现✈️✈️
- ✈️✈️✈️3. test.c 用户交互界面✈️✈️✈️
- 七、感谢与交流
一 、代码搭建:🎈
使用VS2022编译器进行编译
test.c文件实现整个框架,contact.c文件实现整个通讯录的具体功能,contact.h文件实现整个通讯录需要的声明和头文件 🍖 🦴
二 、代码思路:🎈🎈
从现在基本流行的通信录中 发现几个必备的信息
1.对联系人的 增 删 改 查
2.显示所有联系人
3.以姓名 对通讯录 进行排序
三、代码实现🎈🎈🎈
1.框架搭建:🍊🍊
基本框架:用do while()实现通讯录的循环,确保实现增删改查显示的一直进行;🍗
menu()菜单函数🍗🍗
switch 进行项目的选择🍗🍗🍗
联系人 通讯录的创建🍗🍗🍗🍗
1.2 菜单函数打印信息交互🍊🍊
编写一个简单的menu()函数,进行菜单的简单实现
3:联系人创建 通讯录创建:🍊🍊
1.定义一个结构体变量 创建一个联系人结构体(包含了 联系人 姓名 性别 年龄 电话 地址);🥩🥩
🥩🥩2. 利用联系人结构体 创建通讯录(里面包含了一个联系人结构体变量 指针 和定义 联系人数量的sz 和内存容量🥩🥩
四、通讯录各种函数 实现:🍭🍭
1.初始化函数: 🥑 🥑 🥑
1.1 静态初始化 🥑 🥑
void InitContact(Contact* con)
{con->sz = 0;//初始化memset(con->data, 0, sizeof(con->data));}
1.2 动态初始化 🥑 🥑
void InitContact(Contact* con)
{con->sz = 0;//初始化con->data =(Peoinfo*) malloc(sizeof(Peoinfo) * DEFALUT_SZ);if (con->data == NULL){printf("通讯录初始失败:%s\n", strerror(errno));return;}con->capicty = DEFALUT_SZ;con->sz = 0;}
1.3 文件初始化 🥑 🥑
void InitContact(Contact* con)
{con->sz = 0;//初始化con->data =(Peoinfo*) malloc(sizeof(Peoinfo) * DEFALUT_SZ);if (con->data == NULL){printf("通讯录初始失败:%s\n", strerror(errno));return;}con->capicty = DEFALUT_SZ;con->sz = 0;//加载信息到通讯录LoadContact(con);}
🍩 🍪 🌰细心的朋友会发现,文件版的初始化和动态版本的初始化只是多加了一个LoadContact(con)函数,其实就是这样子的,在程序运行的时候,调用Init函数将文件当中的内容写到当中🍩 🍪 🌰
2. 添加联系人:🍭🍭
添加联系人 首先考虑内存空间是否充足 (当联系人 数量 和容量 相同时 realloc 进行 扩容) 扩容 以保证 内存空间不会
过度浪费 和不会存不下当前内容 🌎 🌍 🌏
然后开始在通讯录中添加 联系人
添加成功 sz+1;🌎 🌍 🌏
void AddContact(Contact* con)
{//if (con->sz == MAX)//{// printf("通讯录已满,无法增加\n");// return;//} 静态的程序 添加函数int ret=checkCapcity(con);if (ret == 1){printf("请输入名字:");scanf("%s", con->data[con->sz].name);printf("请输入年龄:");scanf("%d", &(con->data[con->sz].age));printf("请输入电话号码:");scanf("%s", (con->data[con->sz].tel));printf("请输入地址:");scanf("%s", (con->data[con->sz].addr));printf("请输入性别:");scanf("%s", con->data[con->sz].sex);//通讯录成员 + 1con->sz++;printf("添加成功!!!\n");}}
checkCapcity函数,作用是检查通讯录当中人数是否满了,满了的话就扩容
int checkCapcity(Contact* con)
{if (con->sz == con->capicty){Peoinfo* ptr =(Peoinfo*) realloc(con->data, sizeof(Peoinfo)* (con->capicty + ADDNUM));if (ptr == NULL){printf("通讯录增容失败:%s\n", strerror(errno));return 0;}else{con->data = ptr;con->capicty += ADDNUM;printf("通讯录增容成功,当前容量为%d\n", con->capicty);}}return 1;
}
在这里呢,如果我们是动态版本以上的🌎 🌍 🌏,我们每次添加联系人信息的时候需要检查一下通讯录当中成员人数是否满人了,🌎 🌍 🌏如果满人的话我们需要用relloc函数重新开辟空间🌎 🌍 🌏
3.删除联系人:🍭🍭
先输入 联系人 姓名 然后自我遍历找到 姓名所在位置 进行联系人删除
删除成功 sz-1;
void DelContact( Contact* con)
{if (con->sz == 0 ){printf("通讯录为空,无法删除\n");return;}printf("输入要删除人的名字:");int pos = Findbyname(con);if (pos == -1){printf("要删除的人不存在\n");return;}//删除pos上的数据for (int j = pos; j < con->sz - 1; j++){con->data[j] = con->data[j + 1];}//memmmove(con->data[i])con->sz--;printf("删除成功\n");}
这里我们用到了静态的Findbyname函数,用于查找联系人
static int Findbyname(Contact *con)
{char name[MAX_NAME] = "0";scanf("%s", name);int i = 0;for (i = 0; i < con->sz; i++){if (0 == strcmp(con->data[i].name, name)){return i;}}return -1;
}
5.查找联系人:🌰🌰
用户输入联系人姓名 按姓名进行查找 找到 在屏幕打印联系人信息 找不到 提示用户🌎 🌍 🌏
void SearchContact(const Contact* con)
{printf("请输入要查找的名字:");int pos = Findbyname(con);if (pos == -1){printf("要查找的人不在\n");return;}int i = pos;printf("%-10s %-5s %-5s %-12s %-30s\n", "姓名", "年龄", "性别", "电话", "地址");printf("\n");printf("%-10s %-5d%-5s %-12s %-30s",con->data[i].name, con->data[i].age, con->data[i].sex,con->data[i].tel, con->data[i].addr);printf("\n");}
6. 显示联系人:🌰🌰
☃️ ⛄️先对 通讯录当中成员人数 进行检查 如果 sz ==0 说明 通讯录中不存在联系人 ☃️ ⛄️
如果sz!=0, 则显示通讯录内容
☃️ ⛄️
void ShowContact(const Contact* con)
{int i = 0;printf("%-10s %-5s %-5s %-12s %-30s\n", "姓名", "年龄", "性别", "电话", "地址");printf("\n");for (i = 0; i < con->sz; i++){printf("%-10s %-5d%-5s %-12s %-30s",con->data[i].name, con->data[i].age, con->data[i].sex,con->data[i].tel, con->data[i].addr);printf("\n");}
}
7.修改联系人:⚓️⚓️
对联系人内容 进行 修改 原理和删除联系人的原理是一样的,采取覆盖方式
先请用户输入 想要修改联系人姓名 然后找到姓名所在位置
对联系人进行修改,并且需要对输入的名字进行查找,☃️ ⛄️照样需要用到Findbyname函数☃️ ⛄️
void ModifyContact(Contact* con)
{printf("请输入要修改人的名字:");int pos = Findbyname(con);if (pos == -1){printf("要修改的人不存在\n"); return;}printf("请输入名字:");scanf("%s", con->data[pos].name);printf("请输入年龄:");scanf("%d", &(con->data[pos].age));printf("请输入电话号码:");scanf("%s", (con->data[pos].tel));printf("请输入地址:");scanf("%s", (con->data[pos].addr));printf("请输入性别:");scanf("%s", con->data[pos].sex);printf("修改成功!!\n");}
8.按姓名对联系人进行排序:⚓️⚓️
原理是采用库函数qsort进行快速排序,根据姓名排序
void SortContact(Contact* con)
{qsort(con->data, con->sz, sizeof(Peoinfo), compare_by_nmae);printf("排序成功!!!\n");ShowContact(con);
}
9.退出通讯录⛱⛱⛱
9.1 静态版本 🚤 🚤
对于静态版本来说,退出程序之后数据全部丢失,没有过多的话语 🍖 🦴
9.2 动态版本 🚤 🚤
动态版本的通讯录,因为我们在此之前调用了malloc函数去堆区开辟一块连续的内存空间,所以我们需要用free函数去释放内存,并将其置 🍖 🦴为NULL
void Destroy(Contact* con)
{free(con->data);con->data = NULL;con->capicty = 0;con->sz = 0;printf("释放内存..........\n");
}
9.3 文件版本 🚤 🚤 🚤
对于文件版本来说,我们在关闭程序之前需要将我们录入的信息存放在一个文件当中,再然后的操作同动态版本的通讯录一样,需要释放内存
void SaveContact(Contact* con)
{FILE* fp = fopen("D:\\code test\\c-language\\address list\\contact.txt", "wb");if (fp == NULL){perror("SaveContact:fopen");return;}for (int i = 0; i < con->sz; i++){fwrite(con->data + i, sizeof(Peoinfo), 1, fp);}fclose(fp);fp = NULL;printf("成功保存到文件中.........\n");
}void Destroy(Contact* con)
{free(con->data);con->data = NULL;con->capicty = 0;con->sz = 0;printf("释放内存..........\n");
}
五、contact.h 头文件的声明🚀 🛸🚀 🛸
🍖 🦴平时我们为了防止头文件的重复包含,会使用#ifndef或者#program once。这里记录一下它们之间的区别 🍖 🦴
六、🚀 🛸源码分享(以文件版本为主)🚀 🛸
✈️1. contact.h 头文件✈️
#pragma once#define MAX 100
#define MAX_NAME 20
#define MAX_SEX 10
#define MAX_TELE 20
#define MAX_ADDR 20
#define DEFALUT_SZ 3
#define ADDNUM 2
#include<stdio.h>
#include<string.h>
#include<stdlib.h>typedef struct Peoinfo
{char name[MAX_NAME];int age;char sex[MAX_SEX];char tel[MAX_TELE];char addr[MAX_ADDR];}Peoinfo;typedef struct Contact
{Peoinfo *data;int sz;int capicty;
}Contact;void InitContact(Contact* con);void AddContact(Contact* con);void ShowContact(const Contact* con);void DelContact( Contact* con);void SearchContact(const Contact* con);void ModifyContact(Contact* con);void SortContact(Contact* con);void Destroy(Contact* con);void SaveContact(Contact* con);
✈️✈️2. contact.c 通讯录功能实现✈️✈️
#define _CRT_SECURE_NO_WARNINGS#include"contact.h"// 静态版本
//void InitContact(Contact* con)
//{
// con->sz = 0;
// //初始化
// memset(con->data, 0, sizeof(con->data));
//
//}//函数声明
int checkCapcity(Contact* con);void LoadContact(Contact* con)
{FILE* fp = fopen("D:\\code test\\c-language\\address list\\contact.txt", "rb");if (fp == NULL){perror("LoadContact:fopen");return;}Peoinfo tmp = { 0 };while (fread(&tmp, sizeof(Peoinfo), 1, fp)){checkCapcity(con);con->data[con->sz] = tmp;con->sz++;}fclose(fp);fp = NULL;}void InitContact(Contact* con)
{con->sz = 0;//初始化con->data =(Peoinfo*) malloc(sizeof(Peoinfo) * DEFALUT_SZ);if (con->data == NULL){printf("通讯录初始失败:%s\n", strerror(errno));return;}con->capicty = DEFALUT_SZ;con->sz = 0;//加载信息到通讯录LoadContact(con);}static int Findbyname(Contact *con)
{char name[MAX_NAME] = "0";scanf("%s", name);int i = 0;for (i = 0; i < con->sz; i++){if (0 == strcmp(con->data[i].name, name)){return i;}}return -1;}int checkCapcity(Contact* con)
{if (con->sz == con->capicty){Peoinfo* ptr =(Peoinfo*) realloc(con->data, sizeof(Peoinfo)* (con->capicty + ADDNUM));if (ptr == NULL){printf("通讯录增容失败:%s\n", strerror(errno));return 0;}else{con->data = ptr;con->capicty += ADDNUM;printf("通讯录增容成功,当前容量为%d\n", con->capicty);}}return 1;
}//增加信息void AddContact(Contact* con)
{//if (con->sz == MAX)//{// printf("通讯录已满,无法增加\n");// return;//}int ret=checkCapcity(con);if (ret == 1){printf("请输入名字:");scanf("%s", con->data[con->sz].name);printf("请输入年龄:");scanf("%d", &(con->data[con->sz].age));printf("请输入电话号码:");scanf("%s", (con->data[con->sz].tel));printf("请输入地址:");scanf("%s", (con->data[con->sz].addr));printf("请输入性别:");scanf("%s", con->data[con->sz].sex);//通讯录成员 + 1con->sz++;printf("添加成功!!!\n");}}void ShowContact(const Contact* con)
{int i = 0;printf("%-10s %-5s %-5s %-12s %-30s\n", "姓名", "年龄", "性别", "电话", "地址");printf("\n");for (i = 0; i < con->sz; i++){printf("%-10s %-5d%-5s %-12s %-30s",con->data[i].name, con->data[i].age, con->data[i].sex,con->data[i].tel, con->data[i].addr);printf("\n");}
}void DelContact( Contact* con)
{if (con->sz == 0 ){printf("通讯录为空,无法删除\n");return;}printf("输入要删除人的名字:");int pos = Findbyname(con);if (pos == -1){printf("要删除的人不存在\n");return;}//删除pos上的数据for (int j = pos; j < con->sz - 1; j++){con->data[j] = con->data[j + 1];}//memmmove(con->data[i])con->sz--;printf("删除成功\n");}void SearchContact(const Contact* con)
{printf("请输入要查找的名字:");int pos = Findbyname(con);if (pos == -1){printf("要查找的人不在\n");return;}int i = pos;printf("%-10s %-5s %-5s %-12s %-30s\n", "姓名", "年龄", "性别", "电话", "地址");printf("\n");printf("%-10s %-5d%-5s %-12s %-30s",con->data[i].name, con->data[i].age, con->data[i].sex,con->data[i].tel, con->data[i].addr);printf("\n");}void ModifyContact(Contact* con)
{printf("请输入要修改人的名字:");int pos = Findbyname(con);if (pos == -1){printf("要修改的人不存在\n"); return;}printf("请输入名字:");scanf("%s", con->data[pos].name);printf("请输入年龄:");scanf("%d", &(con->data[pos].age));printf("请输入电话号码:");scanf("%s", (con->data[pos].tel));printf("请输入地址:");scanf("%s", (con->data[pos].addr));printf("请输入性别:");scanf("%s", con->data[pos].sex);printf("修改成功!!\n");}static int compare_by_nmae(const void* p, const void* q)
{return strcmp(((Peoinfo*)p)->name, ((Peoinfo*)q)->name);
}void SortContact(Contact* con)
{qsort(con->data, con->sz, sizeof(Peoinfo), compare_by_nmae);printf("排序成功!!!\n");ShowContact(con);}void SaveContact(Contact* con)
{FILE* fp = fopen("contact.txt", "wb");if (fp == NULL){perror("SaveContact:fopen");return;}for (int i = 0; i < con->sz; i++){fwrite(con->data + i, sizeof(Peoinfo), 1, fp);}fclose(fp);fp = NULL;printf("成功保存到文件中.........\n");
}void Destroy(Contact* con)
{free(con->data);con->data = NULL;con->capicty = 0;con->sz = 0;printf("释放内存..........\n");
}
✈️✈️✈️3. test.c 用户交互界面✈️✈️✈️
#define _CRT_SECURE_NO_WARNINGS#include"contact.h"void menu()
{printf("******************************\n");printf("********* 0.EXIT ************\n");printf("********* 1. ADD ************\n");printf("********** 2. DEL **************\n");printf("********** 3. SEARCH *************\n");printf("********* 4. MODIFY **********\n");printf("********* 5.SHOW ************\n");printf("********** 6. SORT *************\n");printf("******************************\n");}enum Option
{EXIT,ADD,DEL,SEARCH,MODIFY,SHOW,SORT
};int main()
{Contact con;InitContact(&con);int input = 0;do{menu();printf("请选择:");scanf("%d", &input);switch (input){case ADD:AddContact(&con);break;case DEL:DelContact(&con);break;case SEARCH:SearchContact(&con);break;case SHOW:ShowContact(&con);break;case MODIFY:ModifyContact(&con);case SORT:SortContact(&con);break;case EXIT:SaveContact(&con);Destroy(&con);printf("退出通讯录\n");break;default:printf("选择错误\n");break;}} while (input);return 0;
}
七、感谢与交流
🌹🌹🌹如果大家通过本篇博客收获了,对结构体及枚举,特别是结构体内存对齐和位段在VS当中的存储有了新的认知,那么希望支持一下哦如果还有不明白的,疑惑的话,或者什么比较好的建议的话,可以发到评论区,
我们一起解决,共同进步 ❗️❗️❗️
最后谢谢大家❗️❗️❗️💯💯💯
查看全文
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.dgrt.cn/a/2227457.html
如若内容造成侵权/违法违规/事实不符,请联系一条长河网进行投诉反馈,一经查实,立即删除!
相关文章:
通讯录(静态版+动态版+文件版)
本期带大家一起来学习一下通讯录的三个版本(静态版动态版文件版)🌈🌈🌈 文章目录一 、代码搭建:🎈二 、代码思路:🎈🎈三、代码实现🎈🎈……
华为OD机试-简单的解压缩算法-2022Q4 A卷-Py/Java/JS
现需要实现一种算法,能将一组压缩字符串还原成原始字符串,还原规则如下:
1、字符后面加数字N,表示重复字符N次。例如:压缩内容为A3,表示原始字符串为AAA。 2、花括号中的字符串加数字N,表示花括……
ToBeWritten之内存损坏漏洞
也许每个人出生的时候都以为这世界都是为他一个人而存在的,当他发现自己错的时候,他便开始长大
少走了弯路,也就错过了风景,无论如何,感谢经历 转移发布平台通知:将不再在CSDN博客发布新文章,敬……
ipad手写笔一定要买苹果的吗?性价比ipad手写笔推荐
随着科技的发展,出现了许多新的电子产品及数字装置。比如智能手机,比如ipad平板,比如电容笔等等。而在现实生活中,要想让ipad发挥出最大的作用,就必须要有一支好的电容笔。就像是我们在IPAD平板上记笔记,需……
taro之–配置目录别名
alias
object
用于配置目录别名,从而方便书写代码引用路径。
例如,使用相对路径书写文件引用如下:
import A from ../../components/A
import Utils from ../../utils
import packageJson from ../../package.json
import projectConfi……
使用uview组件报错
报错提示:
15:23:55.172 Module build failed (from ./node_modules/dcloudio/vue-cli-plugin-uni/packages/sass-loader/dist/cjs.js): 15:23:55.172 SassError: Undefined variable: "$u-border-color". 15:23:55.172 on line 208 of E:\xjn\……
设计模式之《代理模式》
——《代理模式》什么是代理模式为什么用代理模式工作中用在哪里设计思路代码实现总结什么是代理模式
代理模式是一种结构型的设计模式,它允许在不改变原有代码的情况下,通过增加一个代理来控制对原有对象的访问。简而言之,代理模式就是将……
uniapp+uview ui
新建uni-ui项目下载安装插件 uView2.0重磅发布,利剑出鞘,一统江湖 – DCloud 插件市场配置
main.js写入(import App from ./App后面)
// 引入并使用 uView 库
import uView from uview-ui;
Vue.use(uView);
项目根目录下App.vue文件引入基础样式&#x……
全局配置取消uniapp默认导航栏
"style" : { "navigationStyle":"custom" }…
npm报错
npm install报错
npm WARN deprecated uuid3.4.0: Please upgrade to version 7 or higher. Older versions may use Math.random() in certaincircumstances, which is known to be problematic. See https://v8.dev/blog/math-random for details.
npm WARN deprecated r……
LC-1157. 子数组中占绝大多数的元素(二分查找+随即猜,摩尔投票+线段树,upper_bound和lower_bound函数)
文章目录[1157. 子数组中占绝大多数的元素](https://leetcode.cn/problems/online-majority-element-in-subarray/)统计每个元素的索引-超时二分查找 随机猜摩尔投票 线段树[剑指 Offer 39. 数组中出现次数超过一半的数字](https://leetcode.cn/problems/shu-zu-zhong-chu-xi……
杭州旭航集团,申请纳斯达克IPO上市,募资9800万美元
来源:猛兽财经 作者:猛兽财经 猛兽财经获悉,为中国企业提供数字内容营销服务的杭州旭航网络科技有限公司的控股公司Xuhang Holdings Ltd(以下简称:旭航集团),近期已向美国证券交易委员会(SEC)提……
深度学习快速参考:11~13
原文:Deep Learning Quick Reference 协议:CC BY-NC-SA 4.0 译者:飞龙 本文来自【ApacheCN 深度学习 译文集】,采用译后编辑(MTPE)流程来尽可能提升效率。 不要担心自己的形象,只关心如何实现目……
基于copula的风光联合场景生成与缩减
目录
1 主要内容
风光出力场景生成方法
2 部分程序
3 程序结果
4 程序链接
点击直达! 1 主要内容
该程序方法复现《融合风光出力场景生成的多能互补微网系统优化配置》风光出力场景生成部分,目前大多数研究的是不计风光出力之间的相关性影响&……
TS 使用自动提示生成对象中的键
TS 使用自动提示生成对象中的键
使用 plain object 而不是 class 的原因主要是在于 redux 中保存的对象需要为可序列化的对象。当然,具体操实现的时候肯定是可以无视这个需求的,不过 Redux 团队强烈建议使用可序列化对象,具体的官方文档说明……
Spring Boot概述(一)
1. SpringBoot 概述
1.1 SpringBoot 概念
SpringBoot提供了一种快速使用Spring的方式,基于约定优于配置的思想,可以让开发人员不必在配置与逻辑业务之间进行思维的切换,全身心的投入到逻辑业务的代码编写中,从而大大提高了开发的……
计算机笔试/面试常见逻辑题/智力题汇总
说明:按种类汇总,难度不分先后,做了分级罗列,方便后续扩充,大家有比较有意思的题目可以在讨论区讨论。 下面有的题题解相对复杂的直接参考了网上的一些解答,而有的题解我认为并不好的也做了补充,……
OpenAI文档翻译——搭建第一个自己的ChatGPT应用
这篇主要是讲了重头到位创建一个基于OpenAI API的应用程序的过程,同时给出了Node.js、Python版本的实例代码。应用程序的构建总体来说是很简单的就是一个接口调用,前提是我们需要提供密匙。
如果想要获取更好的结果返回一个是可以给模型提供一些列子从而……
python以及PyCharm工具的环境安装与配置
这里以Windows为例
Python的安装
当然是到Python官网下载咯,https://www.python.org/downloads/点我直达,如图: 可以下载最新版本,可以下拉找到之前特定的版本安装,如图: 这里先择的是最新版的进行安装……
JavaScript【六】JavaScript中的字符串(String)
文章目录🌟前言🌟字符串(String)🌟单引号和双引号的区别🌟属性🌟 length :字符串的长度🌟 方法🌟 str.charAt(index);🌟 str.charCodeAt(index);🌟 String.fromCharCode(……
编程日记2023/4/16 14:57:29