当前位置: 首页 > news >正文

C语言实现通讯录,包括增删改查以及动态开辟内存,写入文件等功能

文章目录

  • 前言
  • 一、注意
  • 二、源码
    • 1. test.c源文件
    • 2. contact.h头文件
    • 3. contact.c源文件
  • 总结


前言

C语言实现通讯录,包括增删改查以及动态开辟内存,写入文件等功能

一、注意

  • 在通讯录菜单栏使用枚举
  • 定义PeoInfo类型时,每个结构体类型的成员也使用枚举来确定长度
  • 刚开始动态开辟3个PeoInfo类型的内存
  • 若通讯录满员,则每次动态开辟2个PeoInfo类型的内存
  • 每次退出通讯录,都会将现在已经存在的通讯录内容写入当前目录下的.txt文件
  • 每次重新进入通讯录,在初始化阶段会自动读取.txt文件,并存放到内存中,若内存不足,会自动增容

二、源码

1. test.c源文件

#define  _CRT_SECURE_NO_WARNINGS#include "contact.h"enum
{QUIT,ADD,DEL,MODIFY,SEARCH,SHOW,SORT
};void menu()
{printf("*******************************\n");printf("***** 1. Add    2. Del   ******\n");printf("***** 3. Modify 4. Search *****\n");printf("***** 5. Show   6. Sort   *****\n");printf("***** 0. Quit             *****\n");printf("*******************************\n");}int main()
{int input = 0;// 创建变量Contact con = { 0 };// 初始化通讯录信息InitContact(&con);do{menu();printf("请选择:>");scanf("%d", &input);switch (input){case ADD:AddContact(&con);break;case DEL:DelContact(&con);break;case MODIFY:ModifyContact(&con);break;case SEARCH:SearchContact(&con);break;case SHOW:ShowContact(&con);break;case SORT:SortContact(&con);break;case QUIT:SaveContact(&con);DestoryContact(&con);printf("退出通讯录!!!\n");break;default :printf("输入错误!!!\n");break;}} while (input);return 0;
}

2. contact.h头文件

#pragma once#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <assert.h>enum
{MAX_NAME = 20,MAX_SEX = 5,MAX_TELE = 12,MAX_ADDR = 30,DEFAULT_SZ = 3,INC_SZ = 2
};typedef struct PeoInfo
{char name[MAX_NAME];char sex[MAX_SEX];char tele[MAX_TELE];char addr[MAX_ADDR];int age;
}PeoInfo;typedef struct Contact
{PeoInfo* data;int count; // 人物数量int capacity; // 通讯录容量
}Contact;// 初始化通讯录信息
void InitContact(Contact* ps);// 增加通讯录信息
void AddContact(Contact* ps);// 删除通讯录信息
void DelContact(Contact* ps);// 显示通讯录信息
void ShowContact(Contact* ps);// 修改通讯录信息
void ModifyContact(Contact* ps);// 查找指定联系人信息
void SearchContact(Contact* ps);// 排序通讯录
void SortContact(Contact* ps);// 释放开辟空间
void DestoryContact(Contact* ps);// 保存通讯录信息
void SaveContact(Contact* ps);// 加载通讯录信息
void LoadContact(Contact* ps);

3. contact.c源文件

#define  _CRT_SECURE_NO_WARNINGS#include "contact.h"void CheckCap(Contact* ps)
{if (ps->count == ps->capacity){PeoInfo* tmp = (PeoInfo*)realloc(ps->data, (INC_SZ + ps->capacity) * sizeof(PeoInfo));if (NULL == tmp){perror("realloc");return;}ps->data = tmp;tmp = NULL;ps->capacity += INC_SZ;printf("增容成功!!!\n");}
}void LoadContact(Contact* ps)
{FILE* pfread = fopen("contact.txt", "rb");if (pfread == NULL){perror("LoadContact");return;}PeoInfo tmp = { 0 };while (fread(&tmp, sizeof(PeoInfo), 1, pfread) == 1){CheckCap(ps);ps->data[ps->count] = tmp;ps->count++;}fclose(pfread);pfread = NULL;
}// 初始化信息函数
void InitContact(Contact* ps)
{assert(ps);ps->capacity = DEFAULT_SZ;ps->count = 0;ps->data = (PeoInfo*)calloc(DEFAULT_SZ, sizeof(PeoInfo));if (ps->data == NULL){perror("InitContact");return;}// 加载到通讯录中LoadContact(ps);
}// 增加信息函数
void AddContact(Contact* ps)
{assert(ps);// 判断增容CheckCap(ps);// 增加内容printf("请输入姓名:>");scanf("%s", ps->data[ps->count].name);printf("请输入年龄:>");scanf("%d", &(ps->data[ps->count].age));printf("请输入性别:>");scanf("%s", ps->data[ps->count].sex);printf("请输入电话:>");scanf("%s", ps->data[ps->count].tele);printf("请输入住址:>");scanf("%s", ps->data[ps->count].addr);ps->count++;printf("添加成功!!!\n");}int FindByName(Contact* ps)
{char name[MAX_NAME];printf("请输入要操作人的姓名:");scanf("%s", name);int i = 0;for (i = 0; i < ps->count; i++){if (strcmp(ps->data[i].name, name) == 0){return i;}}return -1;
}// 删除信息函数
void DelContact(Contact* ps)
{assert(ps);if (ps->count == 0){printf("通讯录为空,无法删除!!!\n");return;}// 根据名字找信息int pos = FindByName(ps);if (-1 == pos){printf("要删除的信息不存在!!!\n");return;}int i = 0;for (i = pos; i < ps->count; i++){ps->data[i] = ps->data[i + 1];}ps->count--;printf("删除成功!!!\n");
}// 显示通讯录信息函数
void ShowContact(Contact* ps)
{assert(ps);printf("%-20s %-5s %-5s %-12s %-30s\n", "名字", "年龄", "性别", "电话", "地址");int i = 0;for (i = 0; i < ps->count; i++){printf("%-20s %-5d %-5s %-12s %-30s\n", ps->data[i].name, ps->data[i].age, ps->data[i].sex, ps->data[i].tele, ps->data[i].addr);}
}// 修改通讯录信息
void ModifyContact(Contact* ps)
{assert(ps);int pos = FindByName(ps);if (-1 == pos){printf("要修改的人信息不存在!!!\n");return;}printf("请输入姓名:>");scanf("%s", ps->data[pos].name);printf("请输入年龄:>");scanf("%d", &(ps->data[pos].age));printf("请输入性别:>");scanf("%s", ps->data[pos].sex);printf("请输入电话:>");scanf("%s", ps->data[pos].tele);printf("请输入住址:>");scanf("%s", ps->data[pos].addr);printf("修改信息成功!!!\n");
}// 查找指定联系人信息函数
void SearchContact(const Contact* ps)
{assert(ps);int pos = FindByName(ps);if (-1 == pos){printf("要查中的联系人不存在!!!\n");return;}printf("%-20s %-5s %-5s %-12s %-30s\n", "名字", "年龄", "性别", "电话", "地址");printf("%-20s %-5d %-5s %-12s %-30s\n", ps->data[pos].name,ps->data[pos].age,ps->data[pos].sex,ps->data[pos].tele,ps->data[pos].addr);
}int cmp_by_name(const void* e1, const void* e2)
{return strcmp(((PeoInfo*)e1)->name, ((PeoInfo*)e2)->name);
}// 排序通讯录函数
void SortContact(Contact* ps)
{assert(ps);qsort(ps->data, ps->count, sizeof(PeoInfo), cmp_by_name);printf("排序成功!!!\n");
}// 释放开辟空间函数
void DestoryContact(Contact* ps)
{assert(ps);free(ps->data);ps->data = NULL;
}// 保存通讯录信息函数
void SaveContact(Contact* ps)
{FILE* pfwrite = fopen("contact.txt", "wb");if (pfwrite == NULL){perror("SaveContact");}int i = 0;for (i = 0; i < ps->count; i++){fwrite(ps->data+i, sizeof(PeoInfo), 1, pfwrite);}fclose(pfwrite);pfwrite = NULL;
}

总结

C语言实现通讯录,包括增删改查以及动态开辟内存,写入文件等功能

相关文章:

C语言实现通讯录,包括增删改查以及动态开辟内存,写入文件等功能

文章目录 前言一、注意二、源码1. test.c源文件2. contact.h头文件3. contact.c源文件 总结 前言 C语言实现通讯录&#xff0c;包括增删改查以及动态开辟内存&#xff0c;写入文件等功能 一、注意 在通讯录菜单栏使用枚举定义PeoInfo类型时&#xff0c;每个结构体类型的成员…...

flowable多对并发网关跳转的分析

更多ruoyi-nbcio功能请看演示系统 gitee源代码地址 前后端代码&#xff1a; https://gitee.com/nbacheng/ruoyi-nbcio 演示地址&#xff1a;RuoYi-Nbcio后台管理系统 http://218.75.87.38:9666/ 更多nbcio-boot功能请看演示系统 gitee源代码地址 后端代码&#xff1a; h…...

【嵌入式——QT】QT集成Ymodem协议使用UDP进行传输

【嵌入式——QT】QT集成Ymodem协议使用UDP进行传输 Ymodem协议帧的数据格式帧头包号校验 通讯过程握手信号起始帧数据帧结束帧代码块 Ymodem命令 QT实现YmodemFileTransmit.hYmodemFileTransmit.cppBootLoader.hBootLoader.cppYmodem协议源码 Ymodem协议 帧的数据格式 帧头、…...

python笔记(17)输入输出

一、标准输入与输出简介 Python通过内置的sys模块管理标准输入&#xff08;stdin&#xff09;、标准输出&#xff08;stdout&#xff09;和标准错误&#xff08;stderr&#xff09;。但对大多数简单应用而言&#xff0c;直接使用内置函数就足够了。 二、输入&#xff1a;inpu…...

408数据结构总结复习笔记一:线性表

408数据结构总结复习笔记一&#xff1a;线性表 从现在开始慢慢更新我的考研复习笔记系列吧~ PS&#xff1a;主要是我自己个人复习过程中觉得重点的点&#xff0c;大家仅供参考哈~ 上岸&#xff01;&#xff01;&#xff01;大家一起加油! 顺序表和链表的比较 顺序表链表存取…...

Docker——目录迁移

我们在生产环境中安装Docker时&#xff0c;默认的安装目录是/var/lib/docker&#xff0c;而通常情况下&#xff0c;规划给系统盘的目录一般为50G&#xff0c;该目录是比较小的&#xff0c;一旦容器过多或容器日志过多&#xff0c;就可能出现Docker无法运行的情况&#xff0c;所…...

SpringAMQP-消息转换器

这边发送消息接收消息默认是jdk的序列化方式&#xff0c;发送到服务器是以字节码的形式&#xff0c;我们看不懂也很占内存&#xff0c;所以我们要手动设置一下 我这边设置成json的序列化方式&#xff0c;注意发送方和接收方的序列化方式要保持一致 不然回报错。 引入依赖&#…...

轻松拿下指针(5)

文章目录 一、回调函数是什么二、qsort使用举例三、qsort函数的模拟实现 一、回调函数是什么 回调函数就是⼀个通过函数指针调⽤的函数。 如果你把函数的指针&#xff08;地址&#xff09;作为参数传递给另⼀个函数&#xff0c;当这个指针被⽤来调⽤其所指向的函数 时&#x…...

Nginx反向代理配置

一、介绍 Nginx 的反向代理功能在现代网络架构中扮演着至关重要的角色。首先&#xff0c;它充当了客户端与后端服务器之间的中介。当客户端发送请求时&#xff0c;这些请求先到达 Nginx 服务器&#xff0c;Nginx 会根据预先设定的规则和配置&#xff0c;将请求准确地转发到相应…...

突破编程界限:探索AI编程新境界

文章目录 一、AI编程助手1.1 Baidu Comate智能代码助手1.2 阿里云 通义灵码 二、场景需求三、体验步骤3.1 官网下载3.2 手动下载 四、试用感受4.1 提示4.2 注释生成代码4.3 代码生成4.4 选中生成注释4.5 查看变更&新建文件4.6 调优建议4.7 插件使用 五、结尾推荐 一、AI编程…...

C语言(指针)2

Hi~&#xff01;这里是奋斗的小羊&#xff0c;很荣幸各位能阅读我的文章&#xff0c;诚请评论指点&#xff0c;关注收藏&#xff0c;欢迎欢迎~~ &#x1f4a5;个人主页&#xff1a;小羊在奋斗 &#x1f4a5;所属专栏&#xff1a;C语言 本系列文章为个人学习笔记&#x…...

go学习笔记

1基础搭建 1.1&#xff0c;安装vscode https://code.visualstudio.com/download 64位 1.2&#xff0c;Windows 下搭建Go 开发环境-安装和配置 SDK SDK 的全称(Software Development Kit 软件开发工具包) Go 语言的官网为&#xff1a;golang.org , 因为各种原因&#xff0c;可…...

MacApp自动化测试之Automator初体验

今天我们继续讲Automator的使用。 初体验 启动Automator程序&#xff0c;选择【工作流程】类型。从资源库区域依次将获取指定的URL、从网页中获得文本、新建文本文件三个操作拖进工作流创建区域。 然后修改内容&#xff0c;将获取指定的URL操作中的URL替换成https://www.cnb…...

Vue学习v-html

Vue学习v-html 一、前言1、基本用法2、注意事项 二、总结 一、前言 学习 Vue.js 中的 v-html 指令意味着你想要在你的应用程序中动态地渲染 HTML。这个指令允许你将数据中包含的 HTML 代码直接插入到你的模板中&#xff0c;而不是将其作为纯文本处理。虽然这个功能非常强大&am…...

C++并发:锁

一、前言 C中的锁和同步原语的多样化选择使得程序员可以根据具体的线程和数据保护需求来选择最合适的工具。这些工具的正确使用可以大大提高程序的稳定性和性能&#xff0c;本文讨论了部分锁。 二、std::lock 在C中&#xff0c;std::lock 是一个用于一次性锁定两个或多个互斥…...

Git | git log 和 git status 的区别

如是我闻&#xff1a; git log和git status是Git中的两个非常有用的命令&#xff0c;它们用于不同的目的&#xff0c;并提供不同类型的信息。 git log git log命令用于显示一个或多个分支的提交历史记录。这个命令会列出提交历史&#xff0c;包括每次提交的SHA-1哈希值、提交…...

Django 4.x 智能分页get_elided_page_range

Django智能分页 分页效果 第1页的效果 第10页的效果 带输入框的效果 主要函数 # 参数解释 # number: 当前页码&#xff0c;默认&#xff1a;1 # on_each_side&#xff1a;当前页码前后显示几页&#xff0c;默认&#xff1a;3 # on_ends&#xff1a;首尾固定显示几页&#…...

java-spring 09 下.populateBean (方法成员变量的注入@Autowird,@Resource)

1.在populateBean 方法中的一部分&#xff1a;用于Autowird&#xff0c;Resource注入 // 后处理器已经初始化boolean hasInstAwareBpps hasInstantiationAwareBeanPostProcessors();// 需要依赖检查boolean needsDepCheck (mbd.getDependencyCheck() ! AbstractBeanDefinitio…...

赛氪网携手众机构助力第七届京津冀生态修复实践论坛圆满落幕

近日&#xff0c;由北京生态修复学会联合工业固废网、中国老科协国土资源分会共同主办&#xff0c;赛氪网作为支持单位的第七届京津冀生态修复实践论坛在北京温德姆酒店圆满落幕。本次论坛汇聚了众多行业专家、学者以及企业代表&#xff0c;共同探讨生态修复领域的新技术、新方…...

Naive RAG 、Advanced RAG 和 Modular RAG 简介

简介&#xff1a; RAG&#xff08;Retrieval-Augmented Generation&#xff09;系统是一种结合了检索&#xff08;Retrieval&#xff09;和生成&#xff08;Generation&#xff09;的机制&#xff0c;用于提高大型语言模型&#xff08;LLMs&#xff09;在特定任务上的表现。随…...

从深圳崛起的“机器之眼”:赴港乐动机器人的万亿赛道赶考路

进入2025年以来&#xff0c;尽管围绕人形机器人、具身智能等机器人赛道的质疑声不断&#xff0c;但全球市场热度依然高涨&#xff0c;入局者持续增加。 以国内市场为例&#xff0c;天眼查专业版数据显示&#xff0c;截至5月底&#xff0c;我国现存在业、存续状态的机器人相关企…...

1688商品列表API与其他数据源的对接思路

将1688商品列表API与其他数据源对接时&#xff0c;需结合业务场景设计数据流转链路&#xff0c;重点关注数据格式兼容性、接口调用频率控制及数据一致性维护。以下是具体对接思路及关键技术点&#xff1a; 一、核心对接场景与目标 商品数据同步 场景&#xff1a;将1688商品信息…...

el-switch文字内置

el-switch文字内置 效果 vue <div style"color:#ffffff;font-size:14px;float:left;margin-bottom:5px;margin-right:5px;">自动加载</div> <el-switch v-model"value" active-color"#3E99FB" inactive-color"#DCDFE6"…...

Module Federation 和 Native Federation 的比较

前言 Module Federation 是 Webpack 5 引入的微前端架构方案&#xff0c;允许不同独立构建的应用在运行时动态共享模块。 Native Federation 是 Angular 官方基于 Module Federation 理念实现的专为 Angular 优化的微前端方案。 概念解析 Module Federation (模块联邦) Modul…...

OPENCV形态学基础之二腐蚀

一.腐蚀的原理 (图1) 数学表达式&#xff1a;dst(x,y) erode(src(x,y)) min(x,y)src(xx,yy) 腐蚀也是图像形态学的基本功能之一&#xff0c;腐蚀跟膨胀属于反向操作&#xff0c;膨胀是把图像图像变大&#xff0c;而腐蚀就是把图像变小。腐蚀后的图像变小变暗淡。 腐蚀…...

Python+ZeroMQ实战:智能车辆状态监控与模拟模式自动切换

目录 关键点 技术实现1 技术实现2 摘要&#xff1a; 本文将介绍如何利用Python和ZeroMQ消息队列构建一个智能车辆状态监控系统。系统能够根据时间策略自动切换驾驶模式&#xff08;自动驾驶、人工驾驶、远程驾驶、主动安全&#xff09;&#xff0c;并通过实时消息推送更新车…...

MacOS下Homebrew国内镜像加速指南(2025最新国内镜像加速)

macos brew国内镜像加速方法 brew install 加速formula.jws.json下载慢加速 &#x1f37a; 最新版brew安装慢到怀疑人生&#xff1f;别怕&#xff0c;教你轻松起飞&#xff01; 最近Homebrew更新至最新版&#xff0c;每次执行 brew 命令时都会自动从官方地址 https://formulae.…...

五子棋测试用例

一.项目背景 1.1 项目简介 传统棋类文化的推广 五子棋是一种古老的棋类游戏&#xff0c;有着深厚的文化底蕴。通过将五子棋制作成网页游戏&#xff0c;可以让更多的人了解和接触到这一传统棋类文化。无论是国内还是国外的玩家&#xff0c;都可以通过网页五子棋感受到东方棋类…...

jdbc查询mysql数据库时,出现id顺序错误的情况

我在repository中的查询语句如下所示&#xff0c;即传入一个List<intager>的数据&#xff0c;返回这些id的问题列表。但是由于数据库查询时ID列表的顺序与预期不一致&#xff0c;会导致返回的id是从小到大排列的&#xff0c;但我不希望这样。 Query("SELECT NEW com…...

Python常用模块:time、os、shutil与flask初探

一、Flask初探 & PyCharm终端配置 目的: 快速搭建小型Web服务器以提供数据。 工具: 第三方Web框架 Flask (需 pip install flask 安装)。 安装 Flask: 建议: 使用 PyCharm 内置的 Terminal (模拟命令行) 进行安装,避免频繁切换。 PyCharm Terminal 配置建议: 打开 Py…...