9

次のコードを検討してください。

    ifstream in;
    try {
        in.exceptions ( ifstream::failbit | ifstream::badbit );
        in.open(pConfLocation);
    } catch ( ifstream::failure e ) {
        throw std::runtime_error("Can't open configuration file\n");
    }

    vector<string> lns;
    string s;

    in.clear();
    while ( !in.eof() ){
        getline( in, s );
        boost::algorithm::trim(s);
        lns.push_back( s+='\n');
    }

そう:

  1. try-catch ブロックのニーズに合わせて、次の「例外マスク」 ( ifstream::failbit | ifstream::badbit ) を設定しました。ファイルは問題なく開きます。
  2. while{} ブロックでは、ファイルの最後に eofbit が設定されることがわかっています。しかし

例外マスクは、設定されたときにどの状態フラグが例外をスローする必要があるかを指定する、すべてのストリーム オブジェクトの内部値です。

ifstream::eofbitを設定しませんでしたが、実行時に次のエラーが表示されます。

terminate called after throwing an instance of 'std::ios_base::failure'
  what():  basic_ios::clear
The program has unexpectedly finished.

この振る舞いが理解できません。while{}の直前にin.clear()を使用しようとしましたが、効果がありませんでした。clear() 自体がgoodbitを設定し、私の知る限り、「フラグは例外をスローする必要があります」(上記の引用を参照)

削除する場合

        in.exceptions ( ifstream::failbit | ifstream::badbit );

できます。


この場合、 getline() を機能させるにはどうすればよいですか?

4

1 に答える 1

8

問題は入力反復にあります。eofbit次の読み取りが EOF のみを読み取る場合ではなく、最後の読み取りが EOF に達したときにのみ設定されます。後者が発生した場合、failbit同時に設定されます。ここでの議論を参照してください。

あなたの特定のケースでは、ファイルが改行で終わっている場合(おそらくそうです)、getline()その改行までを読み取り、戻ります。eofbitはまだ設定されていません。次にgetline()、EOF に直接遭遇し、そのドキュメントに従って、「関数が要素を抽出しない場合、関数は を呼び出しますsetstate(failbit)。」

于 2012-11-30T18:38:05.593 に答える