2

編集:この本には何の問題もありません。提供されているコードを正しくコピーできなかっただけです。ブロックは、私がブロックのtry-catch外側に置いている間、whileループの内側にあるはずです。


Stroutrupの「プログラミング:C ++を使用した原則と実践」の第7章のセクション7(「エラーからの回復」)について、私が見逃しているかもしれないことがあります。この本を読んだ人が私を助けてくれることを願っています(または実際には誰でも!)。

トークンパーサーを備えた計算機を開発しました。プログラムが無効なトークンを読み取ると、プログラムは終了します。セクション7の目的は、電卓を終了せずにそのようなエラーから回復させることです。私の問題は、本の指示に従った後でも、無効なトークンの後で電卓が終了することです。

これが電卓の完全なコードです。コードを理解するために必要な場合に備えて、std_lib_facilities.hを次に示します

ご覧のとおり、をmain()呼び出します。これは、例外がスローされた場合(無効なトークンが読み取られた場合に発生します)をcalculate()呼び出します。次に、 print char(';')が見つかるまで、Token_streamからすべてを削除します。これにより、次の計算に進むことができます。これにより、別の無効なトークンが含まれないことが期待されます。clean_up_mess()clean_up_mess()

しかし、例外処理が行われた後、プログラムは単に終了します。例外がスローされた場所から再開するには、何をする必要がありますか?そして、作者はこれを説明するのを忘れましたか、それとも私は何かを逃しましたか?

ありがとう。

4

3 に答える 3

4

例外を処理した後、C++はブロックのコードで実行を続行します。catch例外がスローされた場所から「再開」することはありません。

try解決策は、 /catchブロックを:のループに移動することです。whilecalculate()

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 に答える