Jakiś pomysł skąd błędy w trakcie wykonania programu? Wyjście z terminala poniżej:
~/programy_cpp/linked_list ❯ cat menu.h ✘ IOT 13:06:46
#ifndef MENU_H
#define MENU_H
#include <iostream>
#include <string>
#include <vector>
#include <functional>
using menu_item_func = std::function<void()>;
void print_title(const std::string& title);
struct menu_item {
menu_item(const std::string& title_val) : title{title_val} {}
menu_item(const std::string& title_val, menu_item_func action_val)
: title{title_val}, action{action_val} {}
menu_item(const menu_item& item) : title{item.title}, action{item.action} {}
menu_item& operator=(const menu_item& rhs);
friend std::ostream& operator<<(std::ostream& lhs, const menu_item& rhs);
std::string title{};
menu_item_func action{};
};
using menu_items = std::vector<menu_item>;
class menu {
public:
menu(const std::string& title_val);
menu(const std::string& title_val, const std::vector<menu_item>& items_val);
menu(const menu& menu_val);
void loop();
static void noop() { std::cout << "No action defined!\n"; }
private:
void print_choices() const;
char read_choice() const;
static int nesting_level;
bool active{false};
std::string title{};
std::vector<menu_item> items{};
};
#endif // MENU_H
~/programy_cpp/linked_list ❯ cat menu.cpp 13:07:39
#include "menu.h"
int menu::nesting_level = 0;
void print_title(const std::string& title) {
std::size_t title_len = title.size();
std::size_t width = title_len + 4;
for (int i = 0; i < width; ++i) {
std::cout << "*";
}
std::cout << "\n* " << title << " *\n";
for (int i = 0; i < width; ++i) {
std::cout << "*";
}
std::cout << std::endl;
}
menu_item& menu_item::operator=(const menu_item& rhs) {
title = rhs.title;
action = rhs.action;
return *this;
}
std::ostream& operator<<(std::ostream& lhs, const menu_item& rhs) {
return lhs << rhs.title;
}
menu::menu(const std::string& title_val) : title{title_val} {
}
menu::menu(const std::string& title_val, const std::vector<menu_item>& items_val)
: title{title_val}, items{items_val} {
}
menu::menu(const menu& menu_val) {
for (const menu_item& item : menu_val.items) {
items.push_back(item);
}
}
void menu::print_choices() const {
for (int i = 0; i < items.size(); ++i) {
std::cout << i << ") " << items[i] << std::endl;
}
std::cout << "q) ";
if (nesting_level > 1)
std::cout << "Back";
else
std::cout << "Quit";
std::cout << std::endl;
}
char menu::read_choice() const {
char choice;
bool valid{false};
std::cout << "What do you want to do?\n";
do {
print_choices();
std::cout << "Your choice: ";
std::cin >> choice;
if ((choice - '0') < 0 || ((choice - '0') >= items.size()) && (choice != 'q')) {
std::cout << "Invalid choice!\n";
} else {
valid = true;
}
} while (!valid);
return choice;
}
void menu::loop() {
active = true;
++nesting_level;
while (active) {
print_title(title);
char choice = read_choice();
if (choice == 'q') {
--nesting_level;
active = false;
} else {
items[choice].action();
}
}
}
~/programy_cpp/linked_list ❯ cat main.cpp 13:07:41
#include <iostream>
/*#include <string>*/
/*#include "linked_list.h"*/
#include "menu.h"
void display_sth() {
std::cout << "test\n";
}
int main() {
menu_items main_menu_items;
main_menu_items.emplace_back("test", menu::noop);
main_menu_items.emplace_back("display_sth", display_sth);
menu main_menu{"Main menu", main_menu_items};
main_menu.loop();
return 0;
}
~/programy_cpp/linked_list ❯ ./main 13:07:47
*************
* Main menu *
*************
What do you want to do?
0) test
1) display_sth
q) Quit
Your choice: 1
/usr/lib/gcc/x86_64-pc-linux-gnu/14/include/g++-v14/bits/stl_vector.h:1130: std::vector<_Tp, _Alloc>::reference std::vector<_Tp, _Alloc>::operator[](size_type) [with _Tp = menu_item; _Alloc = std::allocator<menu_item>; reference = menu_item&; size_type = long unsigned int]: Assertion '__n < this->size()' failed.
zsh: IOT instruction (core dumped) ./main
~/programy_cpp/linked_list ❯ ./main ✘ IOT 13:07:51
*************
* Main menu *
*************
What do you want to do?
0) test
1) display_sth
q) Quit
Your choice: 0
/usr/lib/gcc/x86_64-pc-linux-gnu/14/include/g++-v14/bits/stl_vector.h:1130: std::vector<_Tp, _Alloc>::reference std::vector<_Tp, _Alloc>::operator[](size_type) [with _Tp = menu_item; _Alloc = std::allocator<menu_item>; reference = menu_item&; size_type = long unsigned int]: Assertion '__n < this->size()' failed.
zsh: IOT instruction (core dumped) ./main
~/programy_cpp/linked_list ❯ ./main ✘ IOT 13:07:55
*************
* Main menu *
*************
What do you want to do?
0) test
1) display_sth
q) Quit
Your choice: q