2016-10-28 5 views
8

ストリームからすべてのデータを読み込んでも、最後まで読み込もうとしないと、ストリームのEOFは設定されません。これがC++ストリームの仕組みですよね?これは働く理由です。しかしstd :: ios_base :: ignore()がEOFビットを設定するのはなぜですか?

#include <sstream> 
#include <cassert> 

char buf[255]; 

int main() 
{ 
    std::stringstream ss("abcdef"); 
    ss.read(buf, 6); 

    assert(!ss.eof()); 
    assert(ss.tellg() == 6); 
} 

、代わりに私はそれをignore()read() INGのデータを、EOFが設定されている場合:

#include <sstream> 
#include <cassert> 

int main() 
{ 
    std::stringstream ss("abcdef"); 
    ss.ignore(6); 

    assert(!ss.eof());  // <-- FAILS 
    assert(ss.tellg() == 6); // <-- FAILS 
} 

これはGCC 4.8とGCCトランク(Coliru)です。

tellg()返信-1(それはtellg()のものです)、これは私がやっていることを迷惑にしています。

標準に準拠していますか?もしそうなら、どの通路と、なぜですか? ignore()はなぜ私が言いましたより多くを読もうとしましたか?

cppreference's ignore() pageでこの現象の原因が見つかりません。私はおそらく.seekg(6, std::ios::cur)の代わりに、そうでしょうか?しかし、私はまだ何が起こっているのか知りたいです。

+2

うわー、これはMSVS上で動作返さないされていません。それもcoliruのclangで失敗しました。私はそれがライブラリであり、コンパイラ自体ではないと思う。 – NathanOliver

+0

'eof'以外の' delim'を指定するとどうなりますか? – dwcanillas

+0

@dwcanillas:[変更なし](http://coliru.stacked-crooked.com/a/bdb33a4a1a87e593)。 –

答えて

4

これはlibstdC++バグだと思います(42875h/t NathanOliver)。 【istream.unformatted]でignore()上の要件は次のとおり

次のいずれか が発生するまで

文字が抽出される。
- n != numeric_limits<streamsize>::max()(18.3.2)とn文字がこれまで
を抽出された - エンド-of-fileは入力シーケンスで発生します(その場合、setstate(eofbit)、 を呼び出し、ios_base::failure(27.5.5.4)をスローする可能性があります)。 - traits::eq_int_type(traits::to_int_type(c), delim)次の使用可能な入力文字 c(この場合はcが抽出されます)。
備考:traits::eq_int_type(delim, traits::eof())の場合、最後の状態は発生しません。

だから我々は二つの条件(最後には無視される)を持っている - 私たちのどちらかがn文字を読んで、またはいくつかの点で我々は、ファイルの終わり、我々はeofbitを設定した場合にはを押してください。しかし、この場合、ストリームからn文字を読み取ることができます(実際にはストリームに6文字あります)。したがって、入力シーケンスでend-of-fileをヒットしません。 libcの

++、eof()が設定され、tellg()は6

+0

あなたが同意してうれしいです。 :) –

+0

しかし、報告書に記載されているように、要件はあまりにも漠然としていて、libstdC++のこのバグにはっきりとラベル付けされています。言い換えれば、最初にEOFがヒットしたかどうかを確認し、その後にn文字がすでに抽出されているかどうかだけを確認する実装を可能にします。あるいは、 'n'文字がすでに抽出されているかどうかを確認し、EOFがヒットしているかどうかをチェックし、最後に両方のチェックの結果を組み合わせます。 – hvd

+0

@hvd:確かに。 –

関連する問題