从用户输入中解析令牌有哪些好的做法?
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 或成员函数作为命令处理程序。
我正在实现一个系统,用户应该向我的程序提供一个命令。然后我将他们输入的字符串拆分为标记,用空格划定,存储在一个向量中。
我最初的想法是使用一堆 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 或成员函数作为命令处理程序。