-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmenufesto.cpp
160 lines (145 loc) · 4.88 KB
/
menufesto.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
#include "menufesto.h"
#include <algorithm>
#include <cctype>
#include <csignal>
#include <cstdlib>
#include <fstream>
#include <iostream>
#ifdef _WIN32
#include <Windows.h>
#else
#include <unistd.h>
#endif
using namespace std;
// Menu constructor implementation.
// Prints the menu name at construction.
Menu::Menu(const string &menu_name) : menu_name(menu_name) {
print_menu_name(menu_name);
}
// Function to clear the screen, works on Windows and Linux.
void Menu::clear_screen(void) {
#ifdef _WIN32
// For Windows
system("cls");
#else
// ANSI escape code to clear the screen for non-Windows systems
cout << "\033[2J\033[1;1H";
#endif
}
// Prints a given menu name.
void Menu::print_menu_name(const string &menu_name) {
cout << "***** " << menu_name << " *****\n";
}
// Obtains a string from the user.
string Menu::get_string(const string &prompt) {
// Register signal handler for SIGINT (Ctrl+C)
signal(SIGINT, quit_program);
string response;
while (true) {
cout << prompt;
// Check to see if the input stream is still good.
if (!getline(cin, response)) {
// If we have reached EOF (e.g., Ctrl+D / Ctrl+C).
if (cin.eof()) {
quit_program(EOF);
} else {
// If there are any other input stream errors, quit the program.
quit_program(1);
}
} else {
// Input stream is good, break the loop.
break;
}
}
return response;
}
// Helper function to validate if a string can be converted to an int
pair<bool, int> Menu::is_valid_int(const string &response) {
try {
// Try to convert the string to an integer.
// If successful, return true and the integer.
return {true, stoi(response)};
} catch (invalid_argument &e) {
// If a std::invalid_argument exception is caught, return false and 0.
return {false, 0};
}
}
// Function to get an integer input from the user.
int Menu::get_int(const string &prompt) {
// Register signal handler for SIGINT (Ctrl+C)
signal(SIGINT, quit_program);
string response;
while (true) {
cout << prompt;
// Check to see if the input stream is still good.
if (!getline(cin, response)) {
// If we have reached EOF (e.g., Ctrl+D / Ctrl+C)
if (cin.eof()) {
quit_program(EOF);
} else {
// If there are any other input stream errors, quit the program.
quit_program(1);
}
} else {
pair<bool, int> parsed = is_valid_int(response);
if (parsed.first) {
// If the string can be parsed to an integer, return the integer
return parsed.second;
} else {
// If the string can't be parsed to an integer, print an error message
cout << "Please enter a valid number: \n";
}
}
}
}
// Helper function to validate if a string can be converted to a float
pair<bool, float> Menu::is_valid_float(const string &response) {
try {
// Try to convert the string to an float.
// If successful, return true and the float.
return {true, stof(response)};
} catch (invalid_argument &e) {
// If a std::invalid_argument exception is caught, return false and 0.
return {false, 0};
}
}
// Function to get an float input from the user.
float Menu::get_float(const string &prompt) {
// Register signal handler for SIGINT (Ctrl+C)
signal(SIGINT, quit_program);
string response;
while (true) {
cout << prompt;
// Check to see if the input stream is still good.
if (!getline(cin, response)) {
// If we have reached EOF (e.g., Ctrl+D / Ctrl+C)
if (cin.eof()) {
quit_program(EOF);
} else {
// If there are any other input stream errors, quit the program.
quit_program(1);
}
} else {
pair<bool, float> parsed = is_valid_float(response);
if (parsed.first) {
// If the string can be parsed to an float, return the float
return parsed.second;
} else {
// If the string can't be parsed to an integer, print an error message
cout << "Please enter a valid float: \n";
}
}
}
}
// Function to handle program termination
void Menu::quit_program(int signal) {
if (signal == SIGINT || signal == EOF) {
// If the program is terminated by SIGINT (Ctrl+C) or EOF (Ctrl+D), print a message
cout << "\nExiting program.\n";
} else {
// If the program is terminated due to an error, print an error message
cerr << "Input error. Exiting program." << std::endl;
}
// Terminate the program with the provided signal code
exit(signal);
}