例外を使用するようにストリームを構成しない限り、EOFと他のエラーを区別するのは非常に簡単です。
最後に確認stream.eof()
してください。
stream.fail()
その前に、またはのように、失敗/非失敗のみをチェックしてください!stream
。good
の反対ではないことに注意してくださいfail
。したがって、一般的には、を見るgood
だけでなく、を見るだけfail
です。
編集:
いくつかのサンプルコード、つまりデータ内の不適切なブール仕様を区別するために変更されたサンプル:
#include <iostream>
#include <sstream>
#include <string>
#include <stdexcept>
using namespace std;
bool throwX( string const& s ) { throw runtime_error( s ); }
bool hopefully( bool v ) { return v; }
bool boolFrom( string const& s )
{
istringstream stream( s );
(stream >> boolalpha)
|| throwX( "boolFrom: failed to set boolalpha mode." );
bool result;
(stream >> result)
|| throwX( "boolFrom: failed to extract 'bool' value." );
char c; stream >> c;
hopefully( stream.eof() )
|| throwX( "boolFrom: found extra characters at end." );
return result;
}
void readbools( istream& is )
{
string word;
while( is >> word )
{
try
{
bool const b = boolFrom( word );
cout << (b ? "T" : "F") << endl;
}
catch( exception const& x )
{
cerr << "!" << x.what() << endl;
}
}
cout << "- " << is.good() << is.eof() << is.fail() << is.bad() << "\n";
}
void testread( string const& s )
{
istringstream is( s );
readbools( is );
}
int main()
{
cout << string( 60, '-' ) << endl;
testread( "true false" );
cout << string( 60, '-' ) << endl;
testread( "true false tr" );
cout << string( 60, '-' ) << endl;
testread( "true false truex" );
}
結果の例:
-------------------------------------------------- ----------
T
F
--0110
-------------------------------------------------- ----------
T
F
!boolFrom:'bool'値の抽出に失敗しました。
--0110
-------------------------------------------------- ----------
T
F
!boolFrom:最後に余分な文字が見つかりました。
--0110
編集2:投稿されたコードと結果に、eof()
私が忘れていたチェックの使用例を追加しました。
編集3:次の対応する例では、OPが提案する読み取り前のスキップ空白ソリューションを使用しています。
#include <iostream>
#include <sstream>
#include <string>
using namespace std;
void readbools( istream& is )
{
bool b;
while( is >> ws && !is.eof() && is >> b ) // <- Proposed scheme.
{
cout << (b ? "T" : "F") << endl;
}
if( is.fail() )
{
cerr << "!readbools: failed to extract 'bool' value." << endl;
}
cout << "- " << is.good() << is.eof() << is.fail() << is.bad() << "\n";
}
void testread( string const& s )
{
istringstream is( s );
is >> boolalpha;
readbools( is );
}
int main()
{
cout << string( 60, '-' ) << endl;
testread( "true false" );
cout << string( 60, '-' ) << endl;
testread( "true false tr" );
cout << string( 60, '-' ) << endl;
testread( "true false truex" );
}
結果の例:
-------------------------------------------------- ----------
T
F
-0100
-------------------------------------------------- ----------
T
F
!readbools:「bool」値の抽出に失敗しました。
--0110
-------------------------------------------------- ----------
T
F
T
!readbools:「bool」値の抽出に失敗しました。
-0010
主な違いは、このアプローチでは、3番目の値が誤って指定されていても(として"truex"
)、3番目のケースで3つの正常に読み取られた値が生成されることです。
つまり、誤った仕様をそのように認識できません。
もちろん、機能しないコードを書く私の能力は、それが機能しないという証拠ではありません。しかし、私は物事をコーディングするのはかなり得意であり"truex"
、このアプローチでは、が正しくないことを検出する方法を見つけることができませんでした(read-words例外ベースのアプローチで行うのは簡単でしたが)。したがって、少なくとも私にとっては、単語の読み取りの例外ベースのアプローチは、正しく動作させるのが簡単であるという意味で、より単純です。