C++学习之路(四)C++ 实现简单的待办事项列表命令行应用 - 示例代码拆分讲解
本期示例介绍:
本期示例《待办事项列表应用》展示了一个简单的任务管理系统,用户可以通过命令行界面执行添加任务、删除任务和显示任务列表等操作。
功能描述:
-
添加任务功能:
- 用户可以输入任务描述,将新的任务添加到任务列表中。
-
删除任务功能:
- 用户可以输入任务索引号,删除相应索引的任务。
-
显示任务列表功能:
- 显示当前所有任务的索引、完成状态和描述信息。
示例涉及的基础知识点:
-
结构体:
- 示例中的
Task
结构体用于表示任务,包含描述和完成状态。
- 示例中的
-
向量容器 (
std::vector
):- 用于存储任务列表。
std::vector<Task>
保存了Task
结构体的实例,实现了动态数组的功能,能够动态添加和删除任务。
- 用于存储任务列表。
-
命令行交互:
- 使用
std::cin
和std::cout
进行命令行输入输出交互,实现了用户和程序的交互。
- 使用
-
函数和模块化设计:
- 将不同功能的代码块封装成函数,如添加任务、删除任务、显示任务列表等,提高了代码的可读性和可维护性。
-
循环 (
do-while
循环):- 用于提供菜单选项,允许用户多次执行操作,直到选择退出。
-
条件语句 (
if-else
):- 用于检查索引的有效性以及其他条件判断,确保操作的有效性。
-
字符串处理:
- 使用
std::string
处理任务描述,使用std::getline
获取用户输入的完整一行描述信息。
- 使用
通过这个示例,初学者能够学习如何使用向量容器管理数据,如何进行基本的输入输出交互,以及如何通过结构化设计实现简单的功能模块化。同时也能加深对函数、循环和条件语句等基本概念的理解。
示例在Clion中运行步骤:
1. 新建项目
2. 粘贴代码
#include <iostream>
#include <vector>struct Task {std::string description;bool completed;
};// 添加任务函数
void addTask(std::vector<Task> &tasks, const std::string &description) {Task newTask{description, false};tasks.push_back(newTask);std::cout << "Task added: " << description << std::endl;
}// 删除任务函数
void removeTask(std::vector<Task> &tasks, int index) {if (index >= 0 && index < tasks.size()) {std::cout << "Task removed: " << tasks[index].description << std::endl;tasks.erase(tasks.begin() + index);} else {std::cout << "Invalid task index!" << std::endl;}
}// 显示任务函数
void displayTasks(const std::vector<Task> &tasks) {std::cout << "Tasks:" << std::endl;for (size_t i = 0; i < tasks.size(); ++i) {std::cout << i + 1 << ". ";if (tasks[i].completed) {std::cout << "[Completed] ";}std::cout << tasks[i].description << std::endl;}
}int main() {std::vector<Task> tasks; // 创建任务列表向量char choice;do {std::cout << "\nTodo List Application\n";std::cout << "1. Add Task\n";std::cout << "2. Remove Task\n";std::cout << "3. Display Tasks\n";std::cout << "4. Quit\n";std::cout << "Enter your choice: ";std::cin >> choice;switch (choice) {case '1': {std::string description;std::cout << "Enter task description: ";std::cin.ignore(); // 忽略前一个输入的换行符std::getline(std::cin, description); // 读取整行输入作为任务描述addTask(tasks, description); // 调用添加任务函数break;}case '2': {int index;std::cout << "Enter task index to remove: ";std::cin >> index;removeTask(tasks, index - 1); // 调用删除任务函数break;}case '3':displayTasks(tasks); // 调用显示任务函数break;case '4':std::cout << "Exiting...\n";break;default:std::cout << "Invalid choice!\n";break;}} while (choice != '4'); // 循环直到用户选择退出return 0;
}
3. 编译运行
先编译一下,看有没有错误
没有错误的话,就开始运行
代码拆解,知识点总结
让我们来拆分讲解一下这个待办事项列表应用,我们可以逐步解释每个部分的作用和实现。
🟥 首先,看一下头文件
#include <iostream>
#include <vector>
这部分是包含了所需的标准库头文件:
<iostream>
:用于输入输出操作。<vector>
:包含了向量容器的定义,用于存储任务列表。
🟥 任务结构体
struct Task {std::string description;bool completed;
};
这个结构体定义了一个任务,包含了任务的描述和完成状态。
🟥 添加任务函数
void addTask(std::vector<Task> &tasks, const std::string &description) {Task newTask{description, false};tasks.push_back(newTask);std::cout << "Task added: " << description << std::endl;
}
这个函数用于向任务列表中添加新任务,将新任务的描述和完成状态初始化后,添加到任务列表中,并输出添加成功的消息。
📢 Tips: tasks.push_back 是什么意思?
当使用 `std::vector` 时,`push_back()` 是用于向向量末尾添加新元素的成员函数。- **`push_back()`:**- `push_back()` 是 `std::vector` 中用于在向量末尾添加新元素的函数。- 该函数接受一个参数,即要添加的新元素。- 它将新元素添加到向量的末尾,向量大小增加一个单位。- 对于基本数据类型或自定义类型,都可以使用 `push_back()` 将其添加到 `std::vector` 中。在这个例子中,`push_back()` 将新任务(由参数 `description` 创建的 `Task` 结构体对象)添加到了 `tasks` 向量的末尾,实现了向任务列表中添加新任务的功能。
🟥 删除任务函数
void removeTask(std::vector<Task> &tasks, int index) {if (index >= 0 && index < tasks.size()) {std::cout << "Task removed: " << tasks[index].description << std::endl;tasks.erase(tasks.begin() + index);} else {std::cout << "Invalid task index!" << std::endl;}
}
这个函数用于从任务列表中删除指定索引的任务,首先检查索引的有效性,然后删除对应索引的任务,并输出删除成功或失败的消息。
📢 Tips: tasks.erase、tasks.begin 是什么意思?
当使用 `std::vector` 时,`erase()` 和 `begin()` 是两个常用的函数和迭代器。- **`tasks.erase()`:**- `erase()` 是 `std::vector` 中用于删除元素的成员函数。它能够删除指定位置的元素,或是一定范围内的元素。- `tasks.erase(iterator)`:这个函数版本接受一个迭代器作为参数,用于删除指定位置的元素。例如,`tasks.erase(tasks.begin() + index)` 将删除位于 `index` 索引位置的元素。- 如果要删除一定范围内的元素,可以使用两个迭代器来指定范围,比如 `tasks.erase(tasks.begin() + startIndex, tasks.begin() + endIndex)`,它会删除从 `startIndex` 到 `endIndex - 1` 索引位置的元素。- **`tasks.begin()`:**- `begin()` 是 `std::vector` 的成员函数,返回指向容器第一个元素的迭代器。- `tasks.begin()` 返回一个迭代器,指向 `tasks` 容器的第一个元素。- 迭代器是用于在容器中定位和遍历元素的对象。在 `std::vector` 中,迭代器允许你访问和操作容器中的元素,如删除、修改或遍历等。在上述示例中,`tasks.erase(tasks.begin() + index)` 这行代码中的 `tasks.begin() + index` 返回了一个指向 `tasks` 容器中第 `index` 位置的迭代器。然后 `erase()` 函数使用这个迭代器来删除对应位置的元素,实现了删除任务的功能。
🟥 显示任务函数
void displayTasks(const std::vector<Task> &tasks) {std::cout << "Tasks:" << std::endl;for (size_t i = 0; i < tasks.size(); ++i) {std::cout << i + 1 << ". ";if (tasks[i].completed) {std::cout << "[Completed] ";}std::cout << tasks[i].description << std::endl;}
}
这个函数用于显示当前的任务列表,遍历所有任务并输出任务的索引、完成状态和描述信息。
🟥 主函数
int main() {std::vector<Task> tasks; // 创建任务列表向量// ...(菜单选项交互)return 0;
}
在主函数中,我们创建了一个空的任务列表向量,并提供了菜单选项的交互,允许用户添加任务、删除任务或显示任务列表。根据用户的选择,调用相应的函数执行对应的操作,直到用户选择退出。
本次的拆分讲解帮助我们理解了每个函数的作用,以及如何通过结构化的方式实现待办事项列表应用的基本功能。
本文就到这里了,感谢您的阅读,明天还有更多的实例学习文章等着你 🎆。别忘了点赞、收藏~ Thanks♪(・ω・)ノ 🍇。
相关文章:

C++学习之路(四)C++ 实现简单的待办事项列表命令行应用 - 示例代码拆分讲解
本期示例介绍: 本期示例《待办事项列表应用》展示了一个简单的任务管理系统,用户可以通过命令行界面执行添加任务、删除任务和显示任务列表等操作。 功能描述: 添加任务功能: 用户可以输入任务描述,将新的任务添加到任务列表中。…...

函数指针数组指针数组传参的本质字符指针
🚀 作者:阿辉不一般 🚀 你说呢:不服输的你,他们拿什么赢 🚀 专栏:爱上C语言 🚀作图工具:draw.io(免费开源的作图网站) 如果觉得文章对你有帮助的话,还请点赞…...
Linux swapon命令教程:如何在Linux中启用和禁用交换空间(附实例教程和注意事项)
Linux swapon命令介绍 Linux的swapon命令用于启用指定设备和文件的交换。当物理内存(RAM)达到其最大容量时,Linux使用交换空间。如果系统需要更多的内存,而RAM不足,内存中的非活动页面将被移动到交换空间。交换空间是…...

云计算领域的第三代浪潮!
根据IDC不久前公布的数据,2023年上半年中国公有云服务整体市场规模(IaaS/PaaS/SaaS)为190.1亿美元,阿里云IaaS、PaaS市场份额分别为29.9%和27.9%,都远超第二名,是无可置疑的行业领头羊。 随着人工智能(AI)…...
面试题目总结(一)
1. 谈谈数据库的乐观锁和悲观锁 乐观锁和悲观锁是数据库并发控制中常用的两种策略,用于处理多个事务同时访问和修改同一个数据时的并发冲突问题。 数据库的乐观锁是指在读取数据时,不对数据进行加锁,而是在更新数据时检查数据版本是否发生变…...
建造者设计模式
3. 建造者设计模式 3.1 原理 Builder 模式,中文翻译为建造者模式或者构建者模式,也有人叫它生成器模式。 建造者模式是用来创建一种类型的复杂对象,通过设置不同的可选参数,“定制化”地创建不同的对象。 创建者模式主要包含以…...

YOLO目标检测——垃圾检测数据集下载分享【含对应voc、coco和yolo三种格式标签】
实际项目应用:智能化垃圾分类系统、垃圾回收和处理领域的优化管理等方面数据集说明:垃圾分类检测数据集,真实场景的高质量图片数据,数据场景丰富,含报纸、蛋壳、矿泉水瓶、电池、拉链顶罐、塑料餐盒、纸质药盒、香蕉皮…...
Vue CLI的介绍【vue利器之一】
文章目录 前言Vue CLI 介绍CLICLI 服务CLI 插件后言 前言 hello world欢迎来到前端的新世界 😜当前文章系列专栏:vue.js 🐱👓博主在前端领域还有很多知识和技术需要掌握,正在不断努力填补技术短板。(如果出现错误&am…...
【学习笔记】插值之拉格朗日插值(Lagrange)
0 插值介绍 插值法是广泛应用于理论研究和工程实际的重要数值方法。用提供的部分离散的函数值来进行理论分析和设计都是极不方便的,因此希望能够用一个既能反映原函数特征,又便于计算的简单函数去近似原函数。 1 低次拉格朗日插值 定理:设…...

无人机电力巡检系统运行流程全解读
随着电力行业体系不断完善,保障电网运营的安全成为至关重要的任务。传统的人工巡检方式在面对电力设备广泛分布和复杂工况时显得效率低下,为了解决这一难题,无人机电力巡检系统应运而生,以智能化的运行流程,为电网安全…...
有关全局变量和sizeof的题
#define _CRT_SECURE_NO_WARNINGS 1 #include<stdio.h> int i; int main() {i--;if (i > sizeof(i)){printf(">");}else{printf("<");}return 0; } 这道题结果是 > 首先对于一个全局变量,当没有对其初始化时,它…...
vue简述
vue为渐进式框架:vmmv 1.易用 有html、css、javascript基础,即可学习vue框架 2.高效、开发前端页面 非常高效 1.vue的体积小、压缩完只需要20k的大小 2.超快的虚拟dom操作js中非常多的dom操作,vue设计虚拟dom非常快 3.设计时vue底层深度优化 …...

YOLOv8 训练自己的分割数据集
之前写过一篇 使用YOLOv8训练自己的【目标检测】数据集-【收集数据集】-【标注数据集】-【划分数据集】-【配置训练环境】-【训练模型】-【评估模型】-【导出模型】,里面带大家整个流程走过一遍了, 这篇文章我们来介绍如何使用 YOLOv8 训练分割数据集&a…...

Python实现DDos攻击实例详解
文章目录 SYN 泛洪攻击Scapy3k 基本用法代码实现DDos 实现思路argparse 模块socket 模块代码实现Client 端程序测试后记关于Python技术储备一、Python所有方向的学习路线二、Python基础学习视频三、精品Python学习书籍四、Python工具包项目源码合集①Python工具包②Python实战案…...

微信小程序实现【点击 滑动 评分 评星(5星)】功能
wxml文件: <view class"wxpl_xing"><view class"manyidu">{{scoreContent}}</view><view><block wx:for{{scoreArray}} wx:for-item"item"><view classstarLen bindtapchangeScore data-sy"{{…...
堡垒机的用途
堡垒机的用途 堡垒机,即在一个特定的网络环境下,为了保障网络和数据不受来自外部和内部用户的入侵和破坏,而运用各种技术手段监控和记录运维人员对网络内的服务器、网络设备、安全设备、数据库等设备的操作行为,以便集中报警、及时…...

超全超实用行业解决方案合集,覆盖十大行业数据应用需求
现代企业面对复杂的业务需求,对数据分析的需求日益增加。 从实时销售到市场趋势,从客户行为到产品优化,每个环节都依赖于数据支持。然而,传统的数据分析平台常分散在不同系统和团队中,形成数据孤岛,降低了…...

一盏茶的时间,入门 Node.js
一、.什么是 Node.js? Node.js 是一个基于 Chrome V8 引擎的 JavaScript 运行时,用于构建高性能、可伸缩的网络应用。 它采用事件驱动、非阻塞 I/O 模型,使其在处理并发请求时表现出色。 二、安装 Node.js 首先,让我们从 Node.…...
关于Java多线程的一些随笔
Synchronized与ReentrantLock有哪些相同点和不同点? 在Java中,synchronized关键字和ReentrantLock类都用于管理线程间的同步,但它们在实现方式、功能和灵活性方面存在一些差异。以下是它们的相同点和不同点: 相同点 互斥性&…...
Answering difficult questions in other way
I’m not (too) sure Q:Do you think computers make life easier? A:I’m not (too) sure, to be honest, but I reckon they do make life easier because… I can’t say for sure, but … Q:Do you think computers make lif…...
uniapp 对接腾讯云IM群组成员管理(增删改查)
UniApp 实战:腾讯云IM群组成员管理(增删改查) 一、前言 在社交类App开发中,群组成员管理是核心功能之一。本文将基于UniApp框架,结合腾讯云IM SDK,详细讲解如何实现群组成员的增删改查全流程。 权限校验…...
挑战杯推荐项目
“人工智能”创意赛 - 智能艺术创作助手:借助大模型技术,开发能根据用户输入的主题、风格等要求,生成绘画、音乐、文学作品等多种形式艺术创作灵感或初稿的应用,帮助艺术家和创意爱好者激发创意、提高创作效率。 - 个性化梦境…...

从WWDC看苹果产品发展的规律
WWDC 是苹果公司一年一度面向全球开发者的盛会,其主题演讲展现了苹果在产品设计、技术路线、用户体验和生态系统构建上的核心理念与演进脉络。我们借助 ChatGPT Deep Research 工具,对过去十年 WWDC 主题演讲内容进行了系统化分析,形成了这份…...

中南大学无人机智能体的全面评估!BEDI:用于评估无人机上具身智能体的综合性基准测试
作者:Mingning Guo, Mengwei Wu, Jiarun He, Shaoxian Li, Haifeng Li, Chao Tao单位:中南大学地球科学与信息物理学院论文标题:BEDI: A Comprehensive Benchmark for Evaluating Embodied Agents on UAVs论文链接:https://arxiv.…...

23-Oracle 23 ai 区块链表(Blockchain Table)
小伙伴有没有在金融强合规的领域中遇见,必须要保持数据不可变,管理员都无法修改和留痕的要求。比如医疗的电子病历中,影像检查检验结果不可篡改行的,药品追溯过程中数据只可插入无法删除的特性需求;登录日志、修改日志…...

selenium学习实战【Python爬虫】
selenium学习实战【Python爬虫】 文章目录 selenium学习实战【Python爬虫】一、声明二、学习目标三、安装依赖3.1 安装selenium库3.2 安装浏览器驱动3.2.1 查看Edge版本3.2.2 驱动安装 四、代码讲解4.1 配置浏览器4.2 加载更多4.3 寻找内容4.4 完整代码 五、报告文件爬取5.1 提…...
MySQL 索引底层结构揭秘:B-Tree 与 B+Tree 的区别与应用
文章目录 一、背景知识:什么是 B-Tree 和 BTree? B-Tree(平衡多路查找树) BTree(B-Tree 的变种) 二、结构对比:一张图看懂 三、为什么 MySQL InnoDB 选择 BTree? 1. 范围查询更快 2…...
适应性Java用于现代 API:REST、GraphQL 和事件驱动
在快速发展的软件开发领域,REST、GraphQL 和事件驱动架构等新的 API 标准对于构建可扩展、高效的系统至关重要。Java 在现代 API 方面以其在企业应用中的稳定性而闻名,不断适应这些现代范式的需求。随着不断发展的生态系统,Java 在现代 API 方…...
深度学习之模型压缩三驾马车:模型剪枝、模型量化、知识蒸馏
一、引言 在深度学习中,我们训练出的神经网络往往非常庞大(比如像 ResNet、YOLOv8、Vision Transformer),虽然精度很高,但“太重”了,运行起来很慢,占用内存大,不适合部署到手机、摄…...
如何配置一个sql server使得其它用户可以通过excel odbc获取数据
要让其他用户通过 Excel 使用 ODBC 连接到 SQL Server 获取数据,你需要完成以下配置步骤: ✅ 一、在 SQL Server 端配置(服务器设置) 1. 启用 TCP/IP 协议 打开 “SQL Server 配置管理器”。导航到:SQL Server 网络配…...