2

Edit: there's nothing wrong with the book, I simply failed to properly copy the code provided in it. The try-catch block is supposed to be inside the while loop while I've put it outside of it.


There is something I may be missing about Stroutrup's "Programming: Principles and Practice using C++", at chapter 7, section 7 ("Recovering from errors"). I hope someone who read this book will be able to help me (or anyone, actually!).

We have developed a calculator with a token parser. When the program reads an invalid token, it just terminates. Section 7' objective is to make the calculator recover from such errors without terminating. My problem is that after following the book's directives, the calculator still terminates after an invalid token.

Here is the complete code of the calculator. Here is std_lib_facilities.h, in case you need it to understand the code.

As you can see, main() calls for calculate(), which in turn calls for clean_up_mess() if an exception is thrown (which happens when a invalid token is read). clean_up_mess() then removes everything from the Token_stream until the print char (';') is found, so we can go on with the next calculation, which will hopefully not contain another invalid token.

But after the exception handling is done, the program simply terminates. What do I need to do for it to resume where the exception was thrown? And did the author forget to explain this, or did I miss something?

Thanks.

Cutter
  • 1,673
  • 7
  • 27
  • 43
  • 1
    Side note: Make sure you really want exceptions [before you start using it](http://stackoverflow.com/q/1744070/912144). – Shahbaz Jul 15 '12 at 23:00

3 Answers3

4

After handling an exception, C++ continues execution with the code after the catch block. It does not "resume" from where the exception was thrown.

The solution would be to move the try/catch block inside the while loop of 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();
         }
    }
}
Greg Hewgill
  • 951,095
  • 183
  • 1,149
  • 1,285
  • Thanks. It turns out that the code provided in the book did exactly that and that I failed to copy it properly. I feel really dumb now. – Cutter Jul 15 '12 at 23:12
1

This is not a simple problem to solve. I mean, just pointing the error is not going to solve it. When you catch the exception, you call clean_up_mess():

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

However, then the function just exits. And in main(), you don't do anything else apart from calling calculate(), so it ends anyway. In your clean_up_mess function, you just make the stream ignore the offending entries, but anything else.

You have to put your code inside a loop so it is able to follow the execution.

Baltasarq
  • 12,014
  • 3
  • 38
  • 57
1

In your case, while loop reading the input is inside a try-catch block. As a result, when exception is thrown, the loop is terminated and a function returns after handling an exception. What you need to do is to put try-catch block inside a while loop so that it continues to read and process input.