【问题标题】:Std::stoul not being catched after failing in C++在 C++ 中失败后没有捕获 Std::stoul
【发布时间】:2017-10-24 20:25:38
【问题描述】:

我是 C++ 新手,可能缺少一些明显的东西。我想将 OCT 和 HEX 数字转换为 DEC。我可以得到各种错误的输入,所以我想用 std::stoul 进行转换并在失败时捕获。

该方法的重点是在一个字符串中获取 3 个数字。第一个是 OCT,第二个是 DEC,第三个是 HEX。我需要检查它们是否是相同的值。

我从字符串的向量 vec 中获取数字,但这工作正常,我认为问题不存在。

问题是每当方法失败时(例如 OCT 的“88”),整个测试都会失败,并且不会进入 catch 块。

这是我的代码:

bool validate_line(const std::string& str) {
    std::vector<std::string> vec;
    std::string tmp;

    for (int i = 0; i < str.size(); i++){
        if(str.at(i) == ' '){
            vec.push_back(tmp);
            tmp = "";
        }
        else {
            tmp += str.at(i);
            if(i + 1 == str.size()) vec.push_back(tmp);
        }
    }
    if(vec.size() != 3) return false;

    //1 - Octan number
    unsigned long octDec;
    try {
        octDec = std::stoul(vec.at(1), nullptr, 8);
    }
    catch(const std::invalid_argument& ia){
        return false;
    }

    //2 - Decimal
    int dec = atoi( vec.at(2).c_str() );

    //3 - Hex number
    std::string h = vec.at(3).c_str();
    unsigned long hexDec;
    try{
    hexDec = std::stoul(h, nullptr, 16);
    }
    catch(const std::invalid_argument& ia) {
        return false;
    }

    if(octDec == dec && dec == hexDec) return true;
    return false;
}

这些是我对此方法的测试示例。第一个没问题。其余的应该在 catch 块中结束。

TEST_CASE("Line validation", "[small1]") {

    GIVEN("complex improperly tagged equal string") {
        CHECK(validate_line("0111 73 0x49"));
    }

    GIVEN("string not conforming to format -- bad number format") {
        CHECK(!validate_line("88 88 0x58"));
    }

    GIVEN("string not conforming to format -- not numbers") {
        CHECK(!validate_line("07 7 G"));
    }
}

【问题讨论】:

  • 大多数情况下,错误出现在您最不希望出现的代码中。无论如何,您需要提供minimal reproducible example。你怎么知道没有抛出/捕获异常?
  • 我有一个测试方法。因此,无论何时出现输入错误的测试,它都会在 std:stoul 的行上失败,而不是进入 catch 块。
  • 正如我所写的,例如对于 OCT,我发送的不是八进制数的“88”。然后它应该失败并且确实失败了,但它没有捕获任何异常。或者对于 HEX,我可以发送类似“2x”的内容。这种东西是我想要摆脱的。
  • 我编辑了原始帖子并添加了更多信息和代码。
  • 我在原帖中添加了我正在使用的测试。

标签: c++ c++11 exception-handling


【解决方案1】:

您的代码总是在以下行返回:

if(vec.size() != 4) return false;

所以可以抛出的函数永远不会被调用。

此时,对于所有测试输入,vec.size() 始终为 3。

更新:

OP 将有问题的代码行更改为

if(vec.size() != 3) return false;

在这个答案已经发布之后。

【讨论】:

  • 对不起,这只是我显示的代码中的一个错误类型。这不是真正的问题。我已经在原帖中更正了。
  • 请不要在已有有效答案(原始问题)之后更改您的问题,或者至少以某种方式说明您更改了问题,例如UPDATE: 部分
【解决方案2】:

问题确实出在编译器上。我使用 CLion,并且在调试时,如果只有一个 return 语句,它不会显示进入 catch 块的步骤。代码确实没有问题。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-07-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-11-15
    • 2013-02-02
    • 1970-01-01
    • 2016-01-30
    相关资源
    最近更新 更多