C ++捕获拆分人为错误

时间:2014-11-21 19:29:39

标签: c++ vector split

我想知道像“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”,这将使程序崩溃。 提前谢谢。

3 个答案:

答案 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电话中切换了champssplit

这样的事情:

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;
}