C++解决大学课设所有管理系统(增删查改)

C++一篇解决大学课设所有**管理系统(增删查改)

1.引言

​ 话不多说,先看我的任务的需求跟你的是否一致。
在这里插入图片描述

​ (以通讯录管理系统为例),如果你的课设跟以上要求某某管理系统类似的话,也是要求增删查改的话,那么恭喜你刷到此文章。因为所有的大学课设管理系统的套路都是基本一致的。本篇作者将以在实际公司内实际实习考核为参考给大家介绍一份相对规范的管理系统。

本篇是默认存到文件里进行永久读取保存的,如果只是想读入内存一次性的使用,不想这么麻烦,那么请看最后一节。

1.1 使用结果展示

​ 做完后能达一种什么样的结果呢? 直接上截图:

增加:

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

删除:

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

查找:

在这里插入图片描述

在这里插入图片描述

修改:

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

2. 基本原理

​ 这类课设所有核心思路都是:在类vector的序列中存放管理实体对象。例如:

在这里插入图片描述

​ 然后所有的增删查改都是在对里面的对象元素进行修改,从而达到一种管理效果。

3. 文件层次结构

​ 这次实现我们采用面向对象思路:通过对应头文件里面放函数声明相关的.cpp文件来具体实现函数,在main.cpp中只用调用一下对象即可. 例如(以通讯录管理系统为例):

在这里插入图片描述

4.具体实现(通讯录管理系统为例)

4.1 通讯录实体类(addressbook.h)

​ 首先要创建通讯录管理系统,你首先得有一个通讯录吧?,在该类中需要声明(注意只是声明,函数的具体实现放在addressbook.cpp中)所有成员函数和成员变量。那么我们在类中规定通讯录有三种基本元素:姓名、号码、地址。 然后把这三种元素放入private中,public里面要写:获取元素的函数(如:getName() )和设置元素(如: setName() )的函数方便后续修改内容:那么你写完代码后跟我对对,应该有以下内容:

#ifndef __ADDRESSBOOK__
#define __ADDRESSBOOK__
#include<string>class ZqyAddressBook
{public:ZqyAddressBook() {}ZqyAddressBook(const std::string& strName, //构造const std::string& strNumber,const std::string& strAddress):m_strName(strName), m_strNumber(strNumber), m_strAddress(strAddress){}//修改成员函数void setName(const std::string& strName);void setNumber(const std::string& strNumber);void setAddress(const std::string& strAddress);//获取成员函数std::string& getName();std::string& getNumber();std::string& getAddress();private:std::string m_strName; //姓名std::string m_strNumber;//号码std::string m_strAddress;//地址};

4.2 通讯录实现类(addressbook.cpp)

那么我们这个类里面的函数就是实现上述声明的函数,没什么难的,直接上代码:

#include"addressbook.h"void ZqyAddressBook::setName(const std::string& strName) { m_strName = strName; }
void ZqyAddressBook::setNumber(const std::string& strNumber) { m_strNumber = strNumber; }
void ZqyAddressBook::setAddress(const std::string& strAddress) { m_strAddress = strAddress; }std::string&  ZqyAddressBook::getName() { return m_strName; }
std::string&  ZqyAddressBook::getNumber() { return m_strNumber; }
std::string&  ZqyAddressBook::getAddress() { return m_strAddress; }

4.3 通讯录管理类(zqymanager.h)

有了通讯录,我们就开始对通讯录进行增删查改的管理了。在这里创建一个管理类,里面写上增删查改

1.私有成员private: vector m_vecContainer //使用vector存储通讯里对象

2.公有成员public: void menu() // 菜单函数

​ size_t findPerson(const std::string& strName);// 查找人员

​ bool addPerson();//添加人员

​ bool deletePerson();//删除人员

​ bool modifyPerson(const std::string& strName); //修改人员

​ size_t findPersonDemo(const std::string& strName); // 查找人员插件,用于增删查里面判断存在

​ //读入文件相关

​ void loadContactsFromFile();//加载文件

​ void resaveContactsToFile();//重新写入数据,因为删除了某个元素

#ifndef __ZQYMANAGER__
#define __ZQYMANAGER__#include<iostream>
#include<fstream>
#include<string>
#include<vector>
#include<map>
#include"addressbook.h"class ZqyManager{
public:ZqyManager() {}void menu();~ZqyManager() {}void loadContactsFromFile();//加载文件void resaveContactsToFile();//重新写入数据,因为删除了某个元素size_t findPersonDemo(const std::string& strName); // 查找人员插件size_t findPerson(const std::string& strName);// 查找人员bool addPerson();//添加人员bool deletePerson();//删除人员bool modifyPerson(const std::string& strName); //修改人员private:std::vector<ZqyAddressBook> m_vecContainer; //vector存储对象
};

4.4 通讯录管理实现类(zqymanager.cpp)

在这个类里面我们具体实现上述声明出来的函数:

4.4.1 menu()函数

​ 先看代码:我们通过读入用户输入的12345,再通过switch语句来确定我们要调用什么函数

void ZqyManager::menu()
{while (true){std::cout << " " << std::endl;std::cout << "****************************" << std::endl;std::cout << "*******1.添加联系人*********" << std::endl;std::cout << "*******2.删除联系人*********" << std::endl;std::cout << "*******3.查找联系人*********" << std::endl;std::cout << "*******4.修改联系人*********" << std::endl;std::cout << "*******5.保存并退出通讯录*********" << std::endl;std::cout << "****************************" << std::endl;std::cout << "请输入你的选项:";std::string strChoice; //输入类型从int改为string类型,防止std::cin >> int输入string字符串而出现BUG的问题std::cin >> strChoice;std::cout << " " << std::endl;E_Choice eUserChoice = it->second; //改成枚举类型方便下方case理解和维护switch (strChoice){case '1':{addPerson(); //增加函数break;}case '2':{deletePerson();break;}case '3':{std::string strName;std::cout << "请输入您要查询的人员信息:";std::cin >> strName;if (findPerson(strName) == -1) //如果调用查找人员插件函数,没找到的话{std::cout << "查无此人" << std::endl;}break;}case '4':{std::string strName;std::cout << "请输入您要修改的人姓名:";std::cin >> strName;modifyPerson(strName); //调用修改函数break;}case '5':{resaveContactsToFile(); //读入内存函数std::cout << "感谢使用,再见!" << std::endl;std::exit(EXIT_SUCCESS);}default:std::cout << "输入非法,再次输入" << std::endl;break;}}}}
4.4.2 findPersonDemo() 查找人员插件函数

​ 这个函数是为了在增删改的函数里面判断到底存不存在此人的情况而出现。也就是为了别的函数调用的

size_t ZqyManager::findPersonDemo(const std::string& strName) // 查找人员插件
{for (size_t i = 0; i < m_vecContainer.size(); i++){if (m_vecContainer[i].getName() == strName){return i;}}return -1; //返回值为-1 代表不存在
}
4.4.3 findPerson(const std::string& strMsg) 查找人员函数

这个才是正儿八经的查找人员函数了,其实代码大差不差。

{std::vector<ZqyAddressBook> vecTemp;for (auto& it : m_vecContainer){if (it.getName().find(strMsg) != std::string::npos ||it.getNumber().find(strMsg) != std::string::npos ||it.getAddress().find(strMsg) != std::string::npos){vecTemp.push_back(it);}}if (vecTemp.empty()){return -1; //临时vector为空说明一个满足的都没有:查无此人}else{for (auto& it : vecTemp) //输出临时变量中的对象{std::cout << "找到此人:" << it.getName() << " "<< it.getNumber() << " " << it.getAddress() << std::endl;}return 0;}}
4.4.4 添加人员函数 addPerson() 添加人员函数
bool ZqyManager::addPerson() //添加人员
{std::string strName, strNumber, strAddress;std::cout << "请输入您要添加的人员姓名:";std::cin >> strName;std::cout << "请输入您要添加的人员号码:";std::cin >> strNumber;std::cout << "请输入您要添加的人员地址:";std::cin >> strAddress;if (findPersonDemo(strName) != -1) //判断添加人员是否存在{std::cout << "姓名已存在,不保存" << std::endl;return false;}ZqyAddressBook b(strName, strNumber, strAddress);m_vecContainer.push_back(b);std::cout << "人员添加成功!" << std::endl;return true;
}
4.4.5 deletePerson() 删除人员函数
bool ZqyManager::deletePerson() //删除人员
{std::string strName;std::cout << "请输入您要删除的人员姓名:";std::cin >> strName;size_t iTmp = findPersonDemo(strName);if (iTmp != -1){m_vecContainer.erase(m_vecContainer.begin() + findPersonDemo(strName));std::cout << "删除成功! " << std::endl;return true;}std::cout << "没找到这人,删除失败" << std::endl;return false;}
4.4.6 modifyPerson(const std::string& strName) 修改人员函数
bool  ZqyManager::modifyPerson(const std::string& strName)
{if (findPersonDemo(strName) != -1) //找到了{std::string strNewName, strNewNumber, strNewAddress;std::cout << "请输入您要修改成什么名字:";std::cin >> strNewName;std::cout << "请输入您要修改成什么号码:";std::cin >> strNewNumber;std::cout << "请输入您要修改成什么地址:";std::cin >> strNewAddress;for (auto& it : m_vecContainer){if (it.getName() == strName){it.setName(strNewName);it.setNumber(strNewNumber);it.setAddress(strNewAddress);std::cout << "修改成功!!" << std::endl;return true;}}}std::cout << "没找到此联系人,无法修改" << std::endl;return false;}

4.4.7 loadContactsFromFile() 加载文件

通过文件流ifstream来读取文件

void ZqyManager::loadContactsFromFile() //加载文件
{std::ifstream file("booktest.txt");if (!file.is_open()){// 文件不存在,创建一个新文件std::ofstream createFile("booktest.txt");createFile.close();// 重新尝试打开文件file.open("booktest.txt");}if (file.is_open()){ZqyAddressBook object;while (file >> object.getName() >> object.getNumber() >> object.getAddress()){m_vecContainer.push_back(object);}file.close();}
}
4.4.8 resaveCOntactsToFile() 重新写入文件函数

我们光加载进文件后还不够,因为每次增删查改后还要重新更新文件数据


void ZqyManager::resaveContactsToFile() //重新写入数据
{std::ofstream file("booktest.txt");if (file.is_open()){for (auto& it : m_vecContainer){file << it.getName() << " " << it.getNumber() << " "<< it.getAddress() << "\n";}file.close();}
}

4.5 main.cpp

在主函数中我们只用创建对象,然后调用加载文件函数、菜单函数和重新写入文件函数就够了。

#include"addressbook.h"
#include"zqymanager.h"int main()
{ZqyManager test;test.loadContactsFromFile(); //加载文件函数test.menu(); //调用菜单函数,读取到用户输入后自动执行增删查改test.resaveContactsToFile(); //重新读取函数return 0; 
}

5. 简便操作*

​ 如果不想读入写入文件这么麻烦的话,就取消掉loadContacksFromFile()加载文件和resaveCOntactsToFile() 重新写入文件函数,并且在main中注释掉就ok了。

其实只在一次执行的内存中读取就已经能够满足大学管理系统课设的基本要求了!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/804322.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

设备树的概念及引入、设备树如何变成device

在平台总线驱动模型中资源和驱动已经从逻辑上和代码组织上进行了分离&#xff0c;但每次调整资源还是会涉及到内核&#xff0c;所以现在更加流行的是设备树方式。设备树的好处是通过独立于内核存在&#xff0c;这样如果设备上外设功能启用与否以及位置变动的话很多时候不用修改…

【股权激励】“三级股权分配法”——某互联网电商企业股权激励管理

【客户背景及面临难题】K公司于2014年上线&#xff0c;是由多位创始人联合创办的一家以众包微物流配送为核心模式&#xff0c;主营同城水果、蔬菜、生鲜、日常生活用品、零食等商品在线销售&#xff0c;专注于社区生鲜最后一公里配送&#xff0c;主打一小时之内闪电送达的互联网…

Vue自定义指令介绍及使用方法

介绍​ 除了 Vue 内置的一系列指令 (比如 v-model 或 v-show) 之外&#xff0c;Vue 还允许你注册自定义的指令 (Custom Directives)。 之前已经介绍了两种在 Vue 中重用代码的方式&#xff1a;组件 和 组合式函数。组件是主要的构建模块&#xff0c;而组合式函数则侧重于有状态…

使用C语言函数对数组进行操作

前言 在我们了解数组和函数之后&#xff0c;我们对数组和函数进行结合&#xff0c;之后完成一些操作吧 题目描述 杰克想将函数与数组结合进行一些操作&#xff0c;以下是他想要达到的效果&#xff0c;请你帮帮他吧&#xff01; 创建一个整型数组&#xff0c;完成对数组的操作 1…

签约速递 | 看零信任如何打造安全互联的数字底座?

近期&#xff0c;易安联再传佳音&#xff0c;签约南通市公安局、隆基绿能科技股份有限公司、南京体育学院等&#xff0c;持续为客户提供功能更完善、体验更好的零信任安全解决方案&#xff0c;赋能千行百业数字化转型升级&#xff0c;共创网络安全繁荣生态。 南通市公安局 数字…

c语言:getchar()和getch()的区别

1.getchar( ): 使用getchar( )函数读取键盘输入时&#xff0c;只有用户敲击回车键后&#xff0c;getchar( )函数才会返回字符。getchar有一个int型的返回值.当程序调用getchar时.程序就等着用户按键.用户输入的字符被存放在键盘缓冲区(输入缓冲区)中.直到用户按回车为止(回车字…

K-means聚类算法的原理、应用与实例

文章目录 K-means 聚类算法&#xff1a;原理K-means 聚类算法的应用K-means 聚类算法的优化与改进 一个使用 K-means 聚类算法进行客户细分的简单实例 K-means 聚类算法&#xff1a;原理 K-means 算法是一种经典的无监督学习方法&#xff0c;用于对未标记的数据集进行分群&…

智慧公厕是智慧城市建设中不可或缺的一部分

智慧城市的数字化转型正在取得显著成效&#xff0c;各项基础设施的建设也在迅速发展&#xff0c;其中智慧公厕成为了智慧城市体系中不可或缺的一部分。作为社会生活中必要的设施&#xff0c;公共厕所的信息化、数字化、智慧化升级转型能够实现全区域公共厕所管理的横向打通和纵…

数据处理-pandas之多sheet专题

pandas读取具有多个sheet的xlsx文件 import pandas as pddf1 pd.read_excel(data_path, sheet_nameNone) df2 pd.read_excel(data_path) print(df1.keys()) print(df2.keys())两个print不一样&#xff0c;如果不设定sheet_name为None&#xff0c;默认指读取一个sheet&#x…

PostgreSQL介绍

PostgreSQL是一个高度先进的对象关系型数据库管理系&#xff08;ORDBMS&#xff09;&#xff0c;其起源可以追溯到1986年&#xff0c;最初是加州大学伯克利分校计算机系的一个项目&#xff0c;名为POSTGRES。它是从Ingres项目演变而来的&#xff0c;目的是克服当时关系数据库系…

macOS 启动 Nacos(2),50家大厂面试万字精华总结

进来之后一定要选择支持 arm64 的版本不然会出现因为版本不支持导致无法启动 WARNING: The requested images platform (linux/amd64) does not match the detected host platform (linux/arm64/v8) and no specific platform was requested点击 copy docker pull nacos/naco…

Blender2.83 下载地址及安装教程

Blender是一款开源的3D计算机图形软件&#xff0c;广泛应用于动画制作、游戏开发、建模、渲染等领域。它提供了一套强大的工具和功能&#xff0c;让用户能够进行三维建模、动画制作和视觉效果的创作。 Blender支持多种文件格式的导入和导出&#xff0c;使用户能够与其他软件进…

Java中的Lambda表达式和例子

在Java中&#xff0c;Lambda表达式是一种简洁地表示实例化一个只有一个抽象方法的接口&#xff08;函数式接口&#xff09;的方式。它使得代码更加简洁和易读&#xff0c;特别是在处理函数式编程和集合操作时。Lambda表达式的主要组成部分包括参数列表、箭头&#xff08;->&…

Redis从入门到精通(七)Redis实战(四)库存超卖、一人一单与Redis分布式锁

↑↑↑请在文章开头处下载测试项目源代码↑↑↑ 文章目录 前言4.3 优惠券秒杀4.3.4 库存超卖问题及其解决4.3.4.1 问题分析4.3.4.2 问题解决 4.3.5 一人一单需求4.3.5.1 需求分析4.3.5.2 代码实现4.3.5.3 并发问题4.3.5.4 悲观锁解决并发问题4.3.5.5 集群环境下的并发问题 4.4 …

最新版手机软件App下载排行网站源码/App应用商店源码

内容目录 一、详细介绍二、效果展示1.部分代码2.效果图展示 三、学习资料下载 一、详细介绍 一款简洁蓝色的手机软件应用app下载排行&#xff0c;app下载平台&#xff0c;最新手机app发布网站响应式织梦模板。 主要有&#xff1a;主页、app列表页、app介绍详情页、新闻资讯列…

Linux中磁盘的分区,格式化,挂载和文件系统的修复

一.分区工具 1.分区工具介绍 fdisk 2t及以下分区 推荐 (分完区不保存不生效&#xff0c;有反悔的可能) gdisk 全支持 推荐 parted 全支持 不推荐 ( 即时生效&#xff0c;分完立即生效) 2.fdisk 分区,查看磁盘 格式:fdisk -l [磁盘设备] fdisk -l 查看…

网络协议——RSTP(快速生成树)与MSTP(多实例生成树)

一. RSTP 1. STP的不足 1、依靠计时器超时的方式进行收敛导致它的收敛时间需要30到50秒 2、端口状态和端口角色没有细致区分&#xff0c;指导数据转发依靠的不是端口状态而是端口所扮演角色。 3、如果拓扑频繁变化导致用户通信质量差&#xff0c;甚至通信中断&#xf…

详解cmake简单语法与使用

注意&#xff1a;这是一篇cmake入门浅显的文章&#xff0c;深入学习的话没必要阅读。 CMake的使用流程及其语法非常丰富&#xff08;其实就是过于灵活&#xff0c;一个项目一个风格&#xff0c;看上去相当麻烦&#xff09;&#xff0c;下面逐步介绍一些核心概念和常用命令&…

排序:冒泡排序,直接插入排序,简单选择排序,希尔排序,快速排序,堆排序,二路归并排序

目录 一.冒泡排序 代码如下 冒泡排序时间复杂度分析 二.直接插入排序 直接插入排序时间复杂度分析 直接插入排序优化&#xff1a;折半插入排序 三.简单选择排序 简单选择排序优化&#xff1a;双向选择排序 选择排序时间复杂度 双向选择排序时间复杂度 四.希尔排序 希…

rust学习(recursive mutex 实现)

问题&#xff1a; 编写如下代码的时候出现死锁&#xff1a; pub fn test_double_lock() {let t Arc::new(Mutex::new(1));let t1 t.clone();let t2 t.clone();let h std::thread::spawn(move || {println!("hello trace1");let l1 t1.lock().unwrap();println…