Putting it together
- C++ course
- Beginner
- Lesson 87/116
- 6 min
Build a working CLI app with a menu loop.
Putting it together
The final lesson is time to combine all pieces into a working app. The runMenu function takes a list of titles and calls addTask for each. This way the main program can add several tasks with a single call.
Signature: void runMenu(std::vector<Task>& tasks, const std::vector<std::string>& titles). In the body, use a range-based for to walk each title and call addTask(tasks, t). In main, declare a title list, then call runMenu and listTasks. This brings all the building blocks together.
Menu loop
The body of runMenu is a range-based for loop. This loop walks each element of the title vector in order and calls addTask. It is more readable than a classic index loop.
The syntax: for (const std::string& t : titles) { addTask(tasks, t); }. Here t takes one title each iteration; const and & pass it copy-free and read-only. This is the readable and efficient way modern C++ walks a range.
Practice The runMenu function
Define void runMenu(std::vector<Task>& tasks, const std::vector<std::string>& titles). In the body, use a range-based for to call addTask(tasks, t) for each title. In main, declare std::vector<std::string> titles = {"Ekmek al", "Süt al", "Yumurta al"};, then call runMenu(tasks, titles) and listTasks(tasks).
Starter code
#include <iostream>
#include <string>
#include <vector>
struct Task {
std::string title;
bool done;
};
void addTask(std::vector<Task>& tasks, const std::string& title) {
Task t;
t.title = title;
t.done = false;
tasks.push_back(t);
}
void listTasks(const std::vector<Task>& tasks) {
for (size_t i = 0; i < tasks.size(); ++i) {
if (tasks[i].done) {
std::cout << "[x] " << tasks[i].title << "\n";
} else {
std::cout << "[ ] " << tasks[i].title << "\n";
}
}
}
void completeTask(std::vector<Task>& tasks, size_t index) {
if (index < tasks.size()) {
tasks[index].done = true;
}
}
// Define the runMenu function
int main() {
std::vector<Task> tasks;
std::vector<std::string> titles = {"Ekmek al", "Süt al", "Yumurta al"};
// Add runMenu and listTasks calls
return 0;
}Sample solution
#include <iostream>
#include <string>
#include <vector>
struct Task {
std::string title;
bool done;
};
void addTask(std::vector<Task>& tasks, const std::string& title) {
Task t;
t.title = title;
t.done = false;
tasks.push_back(t);
}
void listTasks(const std::vector<Task>& tasks) {
for (size_t i = 0; i < tasks.size(); ++i) {
if (tasks[i].done) {
std::cout << "[x] " << tasks[i].title << "\n";
} else {
std::cout << "[ ] " << tasks[i].title << "\n";
}
}
}
void completeTask(std::vector<Task>& tasks, size_t index) {
if (index < tasks.size()) {
tasks[index].done = true;
}
}
void runMenu(std::vector<Task>& tasks, const std::vector<std::string>& titles) {
for (const std::string& t : titles) {
addTask(tasks, t);
}
}
int main() {
std::vector<Task> tasks;
std::vector<std::string> titles = {"Ekmek al", "Süt al", "Yumurta al"};
runMenu(tasks, titles);
listTasks(tasks);
return 0;
}Expected output
[ ] Ekmek al [ ] Süt al [ ] Yumurta al
Questions and answers
Review the lesson questions together with their answers. To test yourself, solve the lesson interactively.
1 What is the first line of runMenu output?
std::vector<Task> tasks;
std::vector<std::string> titles = {"Ekmek al", "Süt al", "Yumurta al"};
runMenu(tasks, titles);
listTasks(tasks);- 1. Ekmek al
- Ekmek al
- [x] Ekmek al
- [ ] Ekmek al Correct answer
Explanation: The first task is not done yet, so '[ ] Ekmek al' is printed.
2 Match each expression to its meaning
| Term | Meaning |
|---|---|
void runMenu |
Function signature |
for (const std::string& t : titles) |
Range-for |
addTask(tasks, t) |
Add call |
runMenu(tasks, titles) |
Call |
3 runMenu body
for (const std::string& t : ____) { addTask(tasks, t); }
for (const std::string& t : titles) { addTask(tasks, t); }
Explanation: for (const std::string& t : titles) walks the titles.