Skip to content

Instantly share code, notes, and snippets.

@moonheart08
Last active August 25, 2022 16:32
Show Gist options
  • Save moonheart08/bffbce677dbd921ff752d62ac8a9fe94 to your computer and use it in GitHub Desktop.
Save moonheart08/bffbce677dbd921ff752d62ac8a9fe94 to your computer and use it in GitHub Desktop.
// 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