从用户输入中解析令牌有哪些好的做法?

What are good practices to parse tokens from a users input?

我正在实现一个系统,用户应该向我的程序提供一个命令。然后我将他们输入的字符串拆分为标记,用空格划定,存储在一个向量中。

我最初的想法是使用一堆 if-else 语句来根据他们的输入来确定应该触发哪个命令。像这样:

vector<string> userInput;

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

等等。但这似乎很笨拙。有没有更好的做法来解决这样的问题?我已经研究过实施命令模式,即使在使用它时,看起来我也会 运行 遇到将用户输入解析为 instantiate/execute 特定命令的相同问题。

提前致谢!

您可以使用 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&)> 可用于代替普通函数指针,以允许有状态的 lambda 或成员函数作为命令处理程序。