C++ 如何抛出 std::invalid_argument 错误?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/21695935/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-27 23:46:54  来源:igfitidea点击:

How to throw std::invalid_argument error?

c++error-handlingtry-catchinputstreamuser-input

提问by michaelsnowden

I have an overloaded operator in my Fractionclass in C++ which is designed to take input from standard input in the form of an integer over an integer i.e. 1/2or 32/4and initialize a Fractionobject based off of those values. It works, but I'm having trouble catching errors.

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

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

I invoke the method like this:

我像这样调用方法:

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

But whenever an error is thrown, (I'll enter something like garbage) this causes the loop to go on forever without asking for input. What is the reason for this?

但是每当抛出错误时,(我会输入类似的内容garbage)这会导致循环永远继续而不要求输入。这是什么原因?

回答by Arne Mertz

Since you don't tell us what input you give to your program, I can only guess:

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

You type something that cin can't parse as the sequence inputNumerator >> slash >> inputDenominator, so it goes into a fail state or bad state. The exception gets thrown in the else branch of your function (you can and should test that by printing the exception's message in your main function's catch block).

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

Your loop in main goes on, but cinis left in the bad state, so every following input fails again and the same exception is thrown again and again. To prevent that you should clear the state of cin during the error handling. In addition, if there are bad characters in the input stream that can't be parsed, they have to be thrown out, or ignored:

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