本期示例介绍:
本期示例《待办事项列表应用》展示了一个简单的任务管理系统,用户可以通过命令行界面执行添加任务、删除任务和显示任务列表等操作。
功能描述:
-
添加任务功能:
- 用户可以输入任务描述,将新的任务添加到任务列表中。
-
删除任务功能:
- 用户可以输入任务索引号,删除相应索引的任务。
-
显示任务列表功能:
- 显示当前所有任务的索引、完成状态和描述信息。
示例涉及的基础知识点:
-
结构体:
- 示例中的
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♪(・ω・)ノ 🍇。