Last active
August 25, 2022 16:32
-
-
Save moonheart08/bffbce677dbd921ff752d62ac8a9fe94 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// NOTE: Min C++ lang version is C++20. Make sure your project is set to that! | |
#include <iostream> | |
#include <vector> | |
#include <format> | |
#include <stdexcept> | |
#include <string> | |
#include <cassert> | |
using std::cout, std::cin, std::endl; | |
/// <summary> | |
/// Presents a menu asking the user to select from a set of options, of form: | |
/// ``` | |
/// Select one: | |
/// 1) Foo. | |
/// 2) Bar. | |
/// 3) Baz. | |
/// > | |
/// ``` | |
/// </summary> | |
/// <param name="opts">List of options to use.</param> | |
/// <returns>The menu option selected.</returns> | |
int present_menu(std::vector<std::string> opts) { | |
assert(opts.size() > 0); | |
int selection = -1; // VS demands an initializer, but it gets immediately overwritten a few lines from now. | |
do { | |
cout << "Select one:" << endl; | |
for (auto i = 0; i < opts.size(); i++) | |
{ | |
cout << std::format("{}) {}", i + 1, opts[i]) << endl; | |
} | |
cout << "> " << std::flush; | |
cin >> selection; | |
if (cin.fail()) { | |
cin.clear(); // Quit failing. | |
cin.ignore(INT32_MAX, '\n'); // And drain the buffer. | |
selection = -1; | |
continue; | |
} | |
selection--; | |
} while (selection < 0 || selection >= opts.size()); | |
return selection; | |
} | |
/// <summary> | |
/// Different formats the prompt function can use | |
/// </summary> | |
enum PromptFormat { | |
PromptFormat_Entry, // Enter a {}: | |
PromptFormat_Direct, // {} | |
}; | |
/// <summary> | |
/// Prompt the user for a value. | |
/// </summary> | |
/// <typeparam name="T">The value type being prompted for. Must work with std::cin.</typeparam> | |
/// <param name="prompt">The prompt to use</param> | |
/// <param name="form">The "form" for the prompt, see PromptFormat for details.</param> | |
/// <returns>The value entered.</returns> | |
template <typename T> | |
T prompt(std::string prompt, PromptFormat form = PromptFormat_Entry) { | |
switch (form) { | |
case PromptFormat_Entry: | |
cout << std::format("Enter a {}: ", prompt); | |
break; | |
case PromptFormat_Direct: | |
cout << prompt; | |
default: | |
throw new std::invalid_argument("form"); | |
} | |
T value; | |
cin >> value; | |
return value; | |
} | |
int main() | |
{ | |
int x = 'crab'; | |
cout << std::format("{:X}", x) << endl; | |
auto selected = present_menu({ "inches to feet", "feet to inches" }); | |
cout << endl; | |
auto value = prompt<int>("integer in inches"); | |
switch (selected) { | |
case 0: // inches->feet | |
cout << std::format("{} inches is {} feet", value, value / 12.0f) << endl; | |
break; | |
case 1: | |
cout << std::format("{} feet is {} inches", value, value * 12) << endl; | |
break; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment