我想知道像“CMD”一样。我的意思是用户可以在控制台中输入他们的命令。我遇到的问题是每个命令都有效,但是例如,如果我们不写每个args,那么prog会崩溃。 这是代码的一小部分:
void commande(std::string commandeWanted)
{
std::vector<std::string> fields;
boost::split(fields, commandeWanted, boost::is_any_of("|")); // I chose | as spliter
boost::to_upper(fields[0]);
//std::cout<< fields[1] << fields[2] <<std::endl;
if (fields[0] == "STOP")
stop(fields[1]);
else if (fields[0] == "DISCONNECT")
disconnect();
else if (fields[0] == "CONNECT")
connect();
else if (fields[0] == "SEND")
send(fields[1], fields[2]);
else if (fields[0] == "clean")
cleanConsole();
else if (fields[0] == "HELP")
displayHelp();
else
std::cout << "No command recognized." << std::endl;
}
有什么想法吗?有什么建议吗? 我尝试通过声明字段[1]和字段[2],但没办法。 问题是我可以输入“help”这将运行displayHelp函数,但是例如,如果我写“send”而不是“send | who | what”,这将使程序崩溃。 提前谢谢。
答案 0 :(得分:2)
在fields.size() >= 2
访问fields[1]
之前检查fields[2]
,等等{{1}}。
答案 1 :(得分:1)
如果规范化所有函数的外观,可以避免大量的逻辑重复和arg大小检查:
struct Command {
size_t numArgs;
std::function<void(std::vector<std::string>)> fun;
};
std::map<std::string, Command> commands = {
{"STOP", {1, stop}},
{"DISCONNECT", {0, disconnect}},
{"SEND", {2, send}},
// ...
};
// after you split
boost::to_upper(fields[0]);
auto it = commands.find(fields[0]);
if (it != commands.end()) {
// pop the first one
fields.erase(fields.begin());
// check the size
if (fields.size() != it->second.numArgs) {
// error: wrong number of args
}
else {
// ok, call me
it->second.fun(fields);
}
}
else {
// command not found
}
不幸的是,C ++与python *
运算符没有很好的等价物来解包向量 - 但这种方式至少你知道你在所有正确的位置都有所有正确的args,即使你的所有函数都采用了矢量现在。
答案 2 :(得分:0)
在访问代码之前,您需要在代码中添加足够字段的检查。
(看起来你已经在fields
电话中切换了champs
和split
。
这样的事情:
void commande(std::string commandeWanted)
{
std::vector<std::string> fields;
boost::split(fields, commandeWanted, boost::is_any_of("|")); // I chose | as spliter
boost::to_upper(fields[0]);
//std::cout<< fields[1] << fields[2] <<std::endl;
if (fields[0] == "STOP"){
if(fields.size >=2)stop(fields[1]);
}
else if (fields[0] == "DISCONNECT")
disconnect();
else if (fields[0] == "CONNECT")
connect();
else if (fields[0] == "SEND"){
if(fields.size() >= 3)(fields[1], fields[2]);
}
else if (fields[0] == "clean")
cleanConsole();
else if (fields[0] == "HELP")
displayHelp();
else
std::cout << "No command recognized." << std::endl;
}