【问题标题】:How to throw std::invalid_argument error?如何抛出 std::invalid_argument 错误?
【发布时间】:2014-03-08 21:21:16
【问题描述】:

我在 C++ 中的 Fraction 类中有一个重载运算符,该运算符旨在以整数形式从标准输入获取输入,即 1/232/4 并初始化基于 Fraction 对象脱离这些价值观。它可以工作,但我无法捕捉错误。

// gets input from standard input in the form of (hopefully) int/int
std::istream& operator >>(std::istream& inputStream, Fraction& frac)
{
    int inputNumerator, inputDenominator;
    char slash;

    if ((std::cin >> inputNumerator >> slash >> inputDenominator) && slash == '/')
    {
        if (inputDenominator == 0)
        {
            std::cout << "Denominator must not be 0." << std::endl;
            throw std::invalid_argument("Denominator must not be 0.");
        }
        frac.numerator = inputNumerator;
        frac.denominator = inputDenominator;

        frac.reduce();
    }
    else
    {
        throw std::invalid_argument("Invalid syntax.");
    }



    return inputStream;
}

我这样调用方法:

 Fraction frac(1, 2);


while (true)
{
    try {
        std::cout << "Enter a fraction in the form int/int: ";
        std::cin >> frac;
        std::cout << frac;
    } catch (std::invalid_argument iaex) {
        std::cout << "Caught an error!" << std::endl;
    }
}

但无论何时抛出错误,(我会输入类似garbage 的内容)这会导致循环永远持续下去而无需输入。这是什么原因?

【问题讨论】:

  • 对你的代码做一点评论:如果你写一个输入operator&lt;&lt;,你应该使用传递给它的srteam而不是回退到std::cin。然后这可以按预期工作:ifstream if(somefile.txt); if &gt;&gt; frac;
  • 您可能还想通过引用而不是值来捕获异常。
  • 补充@BitTickler 所说的,经验法则是:“按 抛出,按参考 捕获”跨度>

标签: c++ error-handling try-catch inputstream user-input


【解决方案1】:

由于您没有告诉我们您为程序提供了什么输入,我只能猜测:

您键入了 cin 无法解析为序列 inputNumerator &gt;&gt; slash &gt;&gt; inputDenominator 的内容,因此它进入失败状态或错误状态。异常会在函数的 else 分支中引发(您可以而且应该通过在主函数的 catch 块中打印异常消息来测试它)。

您在 main 中的循环继续进行,但 cin 仍处于错误状态,因此每个后续输入都会再次失败,并且会一次又一次地抛出相同的异常。为防止您在错误处理期间清除 cin 的状态。另外,如果输入流中存在无法解析的坏字符,就得扔掉,或者ignored:

if ((std::cin >> inputNumerator >> slash >> inputDenominator) && slash == '/')
{
  /* ... */
}
else
{
    std::cin.clear(); // reset the fail flags
    std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n'); //ignore the bad input until line end
    throw std::invalid_argument("Invalid syntax.");
}

【讨论】:

  • 我稍微编辑了我的问题。我可以输入任何类型的错误输入,这会发生。例如garbage 作为输入或steveaoki。无论如何,我试过这个,它没有用。我认为这可能与我在函数中有一个输入流这一事实有关。
  • @doctordoder 我编辑了答案,我首先错过了错误输入的ignore
  • 我实际上刚刚找到了一个具有相同答案的线程并且它对我有用,所以是的,我可以确认这一点。谢谢!
  • 知道为什么如果我只输入 0 就会失败吗?
  • @doctordoder 它将无法读取您明确想要的斜线和分母。使这些成为可选需要更多的工作。
猜你喜欢
  • 2020-01-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多