我在C ++中的Fraction
类中有一个重载运算符,它被设计为以整数形式从标准输入获取输入,即整数,即1/2
或32/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
的东西)这会导致循环永远继续而不需要输入。这是什么原因?
答案 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.");
}