2

编辑:这本书没有任何问题,我只是未能正确复制其中提供的代码。该try-catch块应该在while循环内,而我把它放在它外面。


关于 Stroutrup 的第 7 章第 7 节(“从错误中恢复”)的“编程:使用 C++ 的原理和实践”,我可能会遗漏一些东西。我希望读过这本书的人能够帮助我(或者任何人,实际上!)。

我们开发了一个带有令牌解析器的计算器。当程序读取一个无效的令牌时,它就终止了。第 7 节的目标是使计算器从此类错误中恢复而不终止。我的问题是,在遵循本书的指示后,计算器仍会在令牌无效后终止。

是计算器的完整代码。是 std_lib_facilities.h,以防您需要它来理解代码。

如您所见,main()调用 for ,如果抛出异常(当读取无效令牌时发生)calculate(),它又调用。然后从 Token_stream 中删除所有内容,直到找到print char (';'),所以我们可以继续下一个计算,希望不会包含另一个无效令牌。clean_up_mess()clean_up_mess()

但是在异常处理完成后,程序就简单地终止了。我需要做什么才能恢复引发异常的地方?作者是否忘记解释这一点,或者我错过了什么?

谢谢。

4

3 回答 3

4

处理异常后,C++ 继续执行该块之后的代码。catch它不会从引发异常的地方“恢复”。

解决方案是将try/catch移动while循环内calculate()

void calculate()
{
    while (cin) {
        try {
            cout << prompt;
            Token t = ts.get();
            while (t.kind == print)
                    t=ts.get();
            if (t.kind == quit) {
                    return;
            }
            ts.putback(t);
            cout << result << expression() << endl;
         } catch (exception& e) {
             cerr << e.what() << endl;
             clean_up_mess();
         }
    }
}
于 2012-07-15T22:57:34.140 回答
1

这不是一个简单的问题要解决。我的意思是,仅仅指出错误并不能解决它。当您捕获异常时,您调用clean_up_mess()

catch (exception& e)
{
        cerr << e.what() << endl;
        clean_up_mess();
}

但是,然后函数就退出了。而在 中main(),除了调用之外,您不会做任何其他事情calculate(),所以无论如何它都会结束。在您的 clean_up_mess 函数中,您只需让流忽略违规条目,但其他任何内容。

您必须将代码放入循环中,以便它能够跟随执行。

于 2012-07-15T22:59:02.470 回答
1

在您的情况下,while循环读取输入位于 try-catch 块内。结果,当抛出异常时,循环终止,处理异常后函数返回。您需要做的是将 try-catch 块放入 while 循环中,以便它继续读取和处理输入。

于 2012-07-15T22:59:09.160 回答