如何抛出std :: invalid_argument错误?

时间:2014-02-11 07:44:12

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

我在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的东西)这会导致循环永远继续而不需要输入。这是什么原因?

1 个答案:

答案 0 :(得分:7)

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

您输入cin无法解析为序列inputNumerator >> slash >> inputDenominator的内容,因此它会进入失败状态或错误状态。异常会在函数的else分支中抛出(您可以并且应该通过在main函数的catch块中打印异常消息来测试它)。

你在main中的循环继续,但是cin处于错误状态,因此每个后续输入都会再次失败,并且会一次又一次地抛出相同的异常。为了防止您在错误处理期间清除cin的状态。此外,如果输入流中存在无法解析的错误字符,则必须将其删除,或ignore d:

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.");
}