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

C++学习之路(四)C++ 实现简单的待办事项列表命令行应用 - 示例代码拆分讲解

本期示例介绍:

本期示例《待办事项列表应用》展示了一个简单的任务管理系统,用户可以通过命令行界面执行添加任务、删除任务和显示任务列表等操作。

在这里插入图片描述

功能描述:

  1. 添加任务功能:

    • 用户可以输入任务描述,将新的任务添加到任务列表中。
  2. 删除任务功能:

    • 用户可以输入任务索引号,删除相应索引的任务。
  3. 显示任务列表功能:

    • 显示当前所有任务的索引、完成状态和描述信息。

示例涉及的基础知识点:

  1. 结构体:

    • 示例中的 Task 结构体用于表示任务,包含描述和完成状态。
  2. 向量容器 (std::vector):

    • 用于存储任务列表。std::vector<Task> 保存了 Task 结构体的实例,实现了动态数组的功能,能够动态添加和删除任务。
  3. 命令行交互:

    • 使用 std::cinstd::cout 进行命令行输入输出交互,实现了用户和程序的交互。
  4. 函数和模块化设计:

    • 将不同功能的代码块封装成函数,如添加任务、删除任务、显示任务列表等,提高了代码的可读性和可维护性。
  5. 循环 (do-while 循环):

    • 用于提供菜单选项,允许用户多次执行操作,直到选择退出。
  6. 条件语句 (if-else):

    • 用于检查索引的有效性以及其他条件判断,确保操作的有效性。
  7. 字符串处理:

    • 使用 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.erasetasks.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++ 实现简单的待办事项列表命令行应用 - 示例代码拆分讲解

本期示例介绍: 本期示例《待办事项列表应用》展示了一个简单的任务管理系统&#xff0c;用户可以通过命令行界面执行添加任务、删除任务和显示任务列表等操作。 功能描述&#xff1a; 添加任务功能&#xff1a; 用户可以输入任务描述&#xff0c;将新的任务添加到任务列表中。…...

函数指针数组指针数组传参的本质字符指针

&#x1f680; 作者&#xff1a;阿辉不一般 &#x1f680; 你说呢&#xff1a;不服输的你&#xff0c;他们拿什么赢 &#x1f680; 专栏&#xff1a;爱上C语言 &#x1f680;作图工具&#xff1a;draw.io(免费开源的作图网站) 如果觉得文章对你有帮助的话&#xff0c;还请点赞…...

Linux swapon命令教程:如何在Linux中启用和禁用交换空间(附实例教程和注意事项)

Linux swapon命令介绍 Linux的swapon命令用于启用指定设备和文件的交换。当物理内存&#xff08;RAM&#xff09;达到其最大容量时&#xff0c;Linux使用交换空间。如果系统需要更多的内存&#xff0c;而RAM不足&#xff0c;内存中的非活动页面将被移动到交换空间。交换空间是…...

云计算领域的第三代浪潮!

根据IDC不久前公布的数据&#xff0c;2023年上半年中国公有云服务整体市场规模(IaaS/PaaS/SaaS)为190.1亿美元&#xff0c;阿里云IaaS、PaaS市场份额分别为29.9%和27.9%&#xff0c;都远超第二名&#xff0c;是无可置疑的行业领头羊。 随着人工智能&#xff08;AI&#xff09;…...

面试题目总结(一)

1. 谈谈数据库的乐观锁和悲观锁 乐观锁和悲观锁是数据库并发控制中常用的两种策略&#xff0c;用于处理多个事务同时访问和修改同一个数据时的并发冲突问题。 数据库的乐观锁是指在读取数据时&#xff0c;不对数据进行加锁&#xff0c;而是在更新数据时检查数据版本是否发生变…...

建造者设计模式

3. 建造者设计模式 3.1 原理 Builder 模式&#xff0c;中文翻译为建造者模式或者构建者模式&#xff0c;也有人叫它生成器模式。 建造者模式是用来创建一种类型的复杂对象&#xff0c;通过设置不同的可选参数&#xff0c;“定制化”地创建不同的对象。 创建者模式主要包含以…...

YOLO目标检测——垃圾检测数据集下载分享【含对应voc、coco和yolo三种格式标签】

实际项目应用&#xff1a;智能化垃圾分类系统、垃圾回收和处理领域的优化管理等方面数据集说明&#xff1a;垃圾分类检测数据集&#xff0c;真实场景的高质量图片数据&#xff0c;数据场景丰富&#xff0c;含报纸、蛋壳、矿泉水瓶、电池、拉链顶罐、塑料餐盒、纸质药盒、香蕉皮…...

Vue CLI的介绍【vue利器之一】

文章目录 前言Vue CLI 介绍CLICLI 服务CLI 插件后言 前言 hello world欢迎来到前端的新世界 &#x1f61c;当前文章系列专栏&#xff1a;vue.js &#x1f431;‍&#x1f453;博主在前端领域还有很多知识和技术需要掌握&#xff0c;正在不断努力填补技术短板。(如果出现错误&am…...

【学习笔记】插值之拉格朗日插值(Lagrange)

0 插值介绍 插值法是广泛应用于理论研究和工程实际的重要数值方法。用提供的部分离散的函数值来进行理论分析和设计都是极不方便的&#xff0c;因此希望能够用一个既能反映原函数特征&#xff0c;又便于计算的简单函数去近似原函数。 1 低次拉格朗日插值 定理&#xff1a;设…...

无人机电力巡检系统运行流程全解读

随着电力行业体系不断完善&#xff0c;保障电网运营的安全成为至关重要的任务。传统的人工巡检方式在面对电力设备广泛分布和复杂工况时显得效率低下&#xff0c;为了解决这一难题&#xff0c;无人机电力巡检系统应运而生&#xff0c;以智能化的运行流程&#xff0c;为电网安全…...

有关全局变量和sizeof的题

#define _CRT_SECURE_NO_WARNINGS 1 #include<stdio.h> int i; int main() {i--;if (i > sizeof(i)){printf(">");}else{printf("<");}return 0; } 这道题结果是 > 首先对于一个全局变量&#xff0c;当没有对其初始化时&#xff0c;它…...

vue简述

vue为渐进式框架&#xff1a;vmmv 1.易用 有html、css、javascript基础&#xff0c;即可学习vue框架 2.高效、开发前端页面 非常高效 1.vue的体积小、压缩完只需要20k的大小 2.超快的虚拟dom操作js中非常多的dom操作&#xff0c;vue设计虚拟dom非常快 3.设计时vue底层深度优化 …...

YOLOv8 训练自己的分割数据集

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

Python实现DDos攻击实例详解

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

微信小程序实现【点击 滑动 评分 评星(5星)】功能

wxml文件&#xff1a; <view class"wxpl_xing"><view class"manyidu">{{scoreContent}}</view><view><block wx:for{{scoreArray}} wx:for-item"item"><view classstarLen bindtapchangeScore data-sy"{{…...

堡垒机的用途

堡垒机的用途 堡垒机&#xff0c;即在一个特定的网络环境下&#xff0c;为了保障网络和数据不受来自外部和内部用户的入侵和破坏&#xff0c;而运用各种技术手段监控和记录运维人员对网络内的服务器、网络设备、安全设备、数据库等设备的操作行为&#xff0c;以便集中报警、及时…...

超全超实用行业解决方案合集,覆盖十大行业数据应用需求

现代企业面对复杂的业务需求&#xff0c;对数据分析的需求日益增加。 从实时销售到市场趋势&#xff0c;从客户行为到产品优化&#xff0c;每个环节都依赖于数据支持。然而&#xff0c;传统的数据分析平台常分散在不同系统和团队中&#xff0c;形成数据孤岛&#xff0c;降低了…...

一盏茶的时间,入门 Node.js

一、.什么是 Node.js&#xff1f; Node.js 是一个基于 Chrome V8 引擎的 JavaScript 运行时&#xff0c;用于构建高性能、可伸缩的网络应用。 它采用事件驱动、非阻塞 I/O 模型&#xff0c;使其在处理并发请求时表现出色。 二、安装 Node.js 首先&#xff0c;让我们从 Node.…...

关于Java多线程的一些随笔

Synchronized与ReentrantLock有哪些相同点和不同点&#xff1f; 在Java中&#xff0c;synchronized关键字和ReentrantLock类都用于管理线程间的同步&#xff0c;但它们在实现方式、功能和灵活性方面存在一些差异。以下是它们的相同点和不同点&#xff1a; 相同点 互斥性&…...

Answering difficult questions in other way

I’m not (too) sure Q&#xff1a;Do you think computers make life easier&#xff1f; A&#xff1a;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&#xff1a;Do you think computers make lif…...

LBE-LEX系列工业语音播放器|预警播报器|喇叭蜂鸣器的上位机配置操作说明

LBE-LEX系列工业语音播放器|预警播报器|喇叭蜂鸣器专为工业环境精心打造&#xff0c;完美适配AGV和无人叉车。同时&#xff0c;集成以太网与语音合成技术&#xff0c;为各类高级系统&#xff08;如MES、调度系统、库位管理、立库等&#xff09;提供高效便捷的语音交互体验。 L…...

地震勘探——干扰波识别、井中地震时距曲线特点

目录 干扰波识别反射波地震勘探的干扰波 井中地震时距曲线特点 干扰波识别 有效波&#xff1a;可以用来解决所提出的地质任务的波&#xff1b;干扰波&#xff1a;所有妨碍辨认、追踪有效波的其他波。 地震勘探中&#xff0c;有效波和干扰波是相对的。例如&#xff0c;在反射波…...

应用升级/灾备测试时使用guarantee 闪回点迅速回退

1.场景 应用要升级,当升级失败时,数据库回退到升级前. 要测试系统,测试完成后,数据库要回退到测试前。 相对于RMAN恢复需要很长时间&#xff0c; 数据库闪回只需要几分钟。 2.技术实现 数据库设置 2个db_recovery参数 创建guarantee闪回点&#xff0c;不需要开启数据库闪回。…...

中南大学无人机智能体的全面评估!BEDI:用于评估无人机上具身智能体的综合性基准测试

作者&#xff1a;Mingning Guo, Mengwei Wu, Jiarun He, Shaoxian Li, Haifeng Li, Chao Tao单位&#xff1a;中南大学地球科学与信息物理学院论文标题&#xff1a;BEDI: A Comprehensive Benchmark for Evaluating Embodied Agents on UAVs论文链接&#xff1a;https://arxiv.…...

UE5 学习系列(三)创建和移动物体

这篇博客是该系列的第三篇&#xff0c;是在之前两篇博客的基础上展开&#xff0c;主要介绍如何在操作界面中创建和拖动物体&#xff0c;这篇博客跟随的视频链接如下&#xff1a; B 站视频&#xff1a;s03-创建和移动物体 如果你不打算开之前的博客并且对UE5 比较熟的话按照以…...

Cinnamon修改面板小工具图标

Cinnamon开始菜单-CSDN博客 设置模块都是做好的&#xff0c;比GNOME简单得多&#xff01; 在 applet.js 里增加 const Settings imports.ui.settings;this.settings new Settings.AppletSettings(this, HTYMenusonichy, instance_id); this.settings.bind(menu-icon, menu…...

3403. 从盒子中找出字典序最大的字符串 I

3403. 从盒子中找出字典序最大的字符串 I 题目链接&#xff1a;3403. 从盒子中找出字典序最大的字符串 I 代码如下&#xff1a; class Solution { public:string answerString(string word, int numFriends) {if (numFriends 1) {return word;}string res;for (int i 0;i &…...

【数据分析】R版IntelliGenes用于生物标志物发现的可解释机器学习

禁止商业或二改转载&#xff0c;仅供自学使用&#xff0c;侵权必究&#xff0c;如需截取部分内容请后台联系作者! 文章目录 介绍流程步骤1. 输入数据2. 特征选择3. 模型训练4. I-Genes 评分计算5. 输出结果 IntelliGenesR 安装包1. 特征选择2. 模型训练和评估3. I-Genes 评分计…...

【p2p、分布式,区块链笔记 MESH】Bluetooth蓝牙通信 BLE Mesh协议的拓扑结构 定向转发机制

目录 节点的功能承载层&#xff08;GATT/Adv&#xff09;局限性&#xff1a; 拓扑关系定向转发机制定向转发意义 CG 节点的功能 节点的功能由节点支持的特性和功能决定。所有节点都能够发送和接收网格消息。节点还可以选择支持一个或多个附加功能&#xff0c;如 Configuration …...

用鸿蒙HarmonyOS5实现中国象棋小游戏的过程

下面是一个基于鸿蒙OS (HarmonyOS) 的中国象棋小游戏的实现代码。这个实现使用Java语言和鸿蒙的Ability框架。 1. 项目结构 /src/main/java/com/example/chinesechess/├── MainAbilitySlice.java // 主界面逻辑├── ChessView.java // 游戏视图和逻辑├──…...