Какова хорошая практика для анализа токенов из пользовательского ввода?

Я внедряю систему, в которой пользователь должен передать моей программе команду. Затем я разделил строку их ввода на токены, разделенные пробелами, которые хранятся в векторе.

Моя первоначальная идея состояла в том, чтобы использовать кучу операторов if-else, чтобы определить, какая команда должна быть запущена на основе их ввода. Примерно так:

vector<string> userInput;

if (userInput[0] == "help") {
//do something
} else if (userInput[0] == "exit") {
//do something else
} else if (....) {

и так далее. Но это кажется неуклюжим. Есть ли лучшие практики для решения такой проблемы? Я уже рассматривал реализацию шаблона Command, и даже при его использовании создается впечатление, что я столкнусь с той же проблемой, связанной с анализом пользовательского ввода для создания экземпляра / выполнения определенной команды.

Заранее спасибо!

-1

Решение

Вы можете использовать std::unordered_map сохранить отображение из имени команды в ее обработчик.

Пример:

#include <unordered_map>
#include <vector>
#include <string>

// The command handlers.
void help(std::vector<std::string> const&);
void exit(std::vector<std::string> const&);

// CommandHandler is a pointer to a function.
using CommandHandler = void(*)(std::vector<std::string> const&);

// Maps a string to a function pointer.
using CommandHandlers = std::unordered_map<char const*, CommandHandler>;

// Associate command names with handlers.
CommandHandlers const command_handlers{
{"help", help},
{"exit", exit},
{"abort", [](auto&) { std::abort(); }} // Can use a stateless lambda.
};

void handle(std::vector<std::string> const& userInput) {
auto found = command_handlers.find(userInput[0].c_str());
if(found == command_handlers.end())
; // Handle invalid command.
else
found->second(userInput); // Invoke the command handler.
}

Вместо массива можно использовать простой массив с линейным или бинарным поиском. std::unordered_map если количество команд мало.

std::function<void(std::vector<std::string> const&)> может использоваться вместо простого указателя на функцию, чтобы разрешить использование лямбда-выражений или функций-членов в качестве обработчиков команд.

2

Другие решения

Других решений пока нет …