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♪(・ω・)ノ 🍇。

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

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

相关文章

声音响度、声压级计权(A B C)实现

声压 sound pressure 声压就是大气压受到声波扰动后产生的变化&#xff0c;即为大气压强的余压&#xff0c;它相当于在大气压强上的叠加一个声波扰动引起的压强变化。由于声压的测量比较容易实现&#xff0c;通过声压的测量也可以间接求得质点速度等其它物理量&#xff0c;所以…

Java中的jvm——面试题+答案(Java虚拟机的基本概念,包括内存区域、类加载机制、垃圾回收等)——第15期

什么是Java虚拟机&#xff08;JVM&#xff09;&#xff1f; 答案&#xff1a; Java虚拟机是Java程序运行的环境&#xff0c;负责将Java源代码编译成字节码&#xff0c;并在运行时执行这些字节码。 Java虚拟机的主要组成部分有哪些&#xff1f; 答案&#xff1a; 主要组成部分…

【开源】基于JAVA的天然气工程业务管理系统

项目编号&#xff1a; S 021 &#xff0c;文末获取源码。 \color{red}{项目编号&#xff1a;S021&#xff0c;文末获取源码。} 项目编号&#xff1a;S021&#xff0c;文末获取源码。 目录 一、摘要1.1 项目介绍1.2 项目录屏 二、功能模块三、使用角色3.1 施工人员3.2 管理员 四…

java编程规范-异常处理\mysql(阿里手册)

( 一 ) 异常处理 1. 【强制】 Java 类库中定义的一类 RuntimeException 可以通过预先检查进行规避&#xff0c;而不应该 通过 catch 来处理&#xff0c;比如&#xff1a; IndexOutOfBoundsException &#xff0c; NullPointerException 等等。 说明&#xff1a; 无法通…

手把手教会你--渗透实战--Hack The Box-Starting Point-Meow--持续更新

有什么问题&#xff0c;请尽情问博主&#xff0c;QQ群796141573 前言 前言 请务必跟着博主复现一遍 参考&#xff1a; Hack The Box-Starting Point-Meow

pygame加载图像,并让小球做平抛运动

文章目录 load转换和存储自由落体 在游戏设计中&#xff0c;图像显示是必不可少的功能&#xff0c;pygame中的image模块便用于加载图像。 load 通过load函数&#xff0c;可以加载多种图像格式&#xff0c;如下表所示 旧版本bmp, gpeg, png, pcx, tiff, xpmc, lbm(以及pbm, p…

windows下docker环境搭建与运行实战

背景 学习docker使用&#xff0c;需要环境&#xff0c;今天主要的目标是在windows环境下安装docker环境。 为什么要这么搞&#xff0c;主要是企业内部服务器&#xff0c;都是跟公网隔离的&#xff0c;没有访问公网权限&#xff0c;所以镜像什么的&#xff0c;从公网拉取完全没…

Ubuntu命令记录

一、基本 查询历史命令记录 history插件支持的分辨率 xrandr设置分辨率以及刷新率 xrandr -s 1920x1080赋予可执行权限 chmod x a.sh关机 sudo shutdown -h 18:00 18点关机 sudo shutdown -r now 立即重启 sudo shutdown -h now 立即关机重启 reboot查看磁…

卷积神经网络(Inception-ResNet-v2)交通标志识别

文章目录 一、前言二、前期工作1. 设置GPU&#xff08;如果使用的是CPU可以忽略这步&#xff09;2. 导入数据3. 查看数据 二、构建一个tf.data.Dataset1.加载数据2. 配置数据集 三、构建Inception-ResNet-v2网络1.自己搭建2.官方模型 五、设置动态学习率六、训练模型七、模型评…

rust tokio select!宏详解

rust tokio select!宏详解 简介 本文介绍Tokio中select!的用法&#xff0c;重点是使用过程中可能遇到的问题&#xff0c;比如阻塞问题、优先级问题、cancel safe问题。在Tokio 中&#xff0c;select! 是一个宏&#xff0c;用于同时等待多个异步任务&#xff0c;并在其中任意一…

探索 Vue 中的 bus.$emit:实现组件通信的强大工具

&#x1f90d; 前端开发工程师&#xff08;主业&#xff09;、技术博主&#xff08;副业&#xff09;、已过CET6 &#x1f368; 阿珊和她的猫_CSDN个人主页 &#x1f560; 牛客高级专题作者、在牛客打造高质量专栏《前端面试必备》 &#x1f35a; 蓝桥云课签约作者、已在蓝桥云…

linux logrotate介绍

我们知道linux系统日志文件位于/var/log目录下,在/var/log目录下,我们会发现有相当一部分日志文件末尾包含一串数字(E.g:ecure-20231114),这表明这部分日志文件经过了日志转储,以避免日志文件过大,导致可读性较差。 [root@rhel77 log]# pwd /var/log [root@rhel77 log]# …

运维高级--centos7源码安装Apache

安装必要的依赖项&#xff1a; sudo yum groupinstall "Development Tools" sudo yum install pcre pcre-devel zlib zlib-devel openssl openssl-devel这将安装编译和构建所需的基本工具&#xff0c;以及 Apache HTTP Server 所需的一些依赖项。 下载 Apache HTT…

Pycharm Available Packages显示Noting to show

使用Pycharm安装依赖包时Available packages 页面点击添加按钮后,没有任何包显示,并且无法搜索安装. 在各种网站查看到的方法如下: 1.网络问题,需要添加镜像源 点击Manage Repositories 添加一个可用的镜像源地址即可 2.打开了anaconda(那个绿色圈圈小图标),再点一下把它点…

如何在 Vim 中剪切、复制和粘贴

目录 前言 如何在 Vim 编辑器中复制文本 如何在 Vim 编辑器中剪切文本 如何在 Vim 编辑器中粘贴文本 如何通过选择文本来剪切和复制文本 通过选择文本复制 在 Vim 中选择文本来剪切文本 前言 在本篇 Vim 快速技巧中&#xff0c;你将学习到剪切和复制粘贴的相关知识。 剪…

【好玩的 Docker 项目】搭建一个简洁的记事本 ——minimalist-web-notepad

前言 搭建一个类似于 notepad 的纯文本笔记本,可以用来做记事本,也可以用来做临时记录的工具。 演示地址:https:/https://chinausdt.com 环境准备 腾讯香港轻量云应用服务器 1 核 1G(24 元 / 月款)域名一枚并做好解析Docker宝塔面板安装 Docker 更新、安装必备软件 BA…

PgSQL技术内幕-Analyze做的那些事-pg_stat_all_tables

PgSQL技术内幕-Analyze做的那些事-pg_stat_all_tables pg_stat_all_tables视图中记录有analyze信息&#xff0c;比如何时做的analyze、表元组个数&#xff08;活元组、死元组&#xff09;等。重启后发现该视图中表的统计信息重置不见了&#xff0c;发生了什么&#xff1f; 1、p…

keyof

// 在TypeScript中&#xff0c;keyof是一个操作符&#xff0c; // 它允许你从一个类型中提取所有的可枚举属性名&#xff0c;并将它们组成一个联合类型。 // 例如&#xff0c;假设你有这样一个类型&#xff1a; type Person { firstName: string; lastName: string; age: n…

HarmonyOS开发者工具DevEco Studio-汉化

HarmonyOS DevEco Studio 简介 下载安装及汉化 打开开发者工具 安装语言包重启 然后设置页搜索“chinese”&#xff0c;选中中文语言包&#xff0c;点击后面的install&#xff1b; 或者 汉化按照IDEA的汉法风格&#xff0c;需要安装插件重启就可以汉化&#xff0c;步骤为&…

在云服务器上搭建个人版chatGPT及后端Spring Boot集成chat GPT

原创/朱季谦 本文分成两部分&#xff0c;包括【国内服务器上搭建chat GPT】和【后端Spring Boot集成chat GPT】。 无论是在【国内服务器上搭建chat GPT】和【后端Spring Boot集成chat GPT】&#xff0c;两个方式都需要魔法访问&#xff0c;否则是无法正常使用的&#xff0c;即…