只要您不将流配置为使用异常,就很容易区分 EOF 和其他错误。
只需stream.eof()
在最后检查。
在此之前只检查失败/非失败,例如stream.fail()
or !stream
。注意good
不是相反的fail
。所以一般从不看good
,只看fail
。
编辑:
一些示例代码,即修改您的示例以区分数据中的不良 bool 规范:
#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" );
}
示例结果:
-------------------------------------------------- ----------
吨
F
- 0110
-------------------------------------------------- ----------
吨
F
!boolFrom: 未能提取 'bool' 值。
- 0110
-------------------------------------------------- ----------
吨
F
!boolFrom: 在末尾发现多余的字符。
- 0110
编辑 2:在发布的代码和结果中,添加了使用eof()
检查的示例,我忘记了。
编辑 3:以下相应示例使用 OP 提出的 skip-whitespace-before-reading 解决方案:
#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" );
}
示例结果:
-------------------------------------------------- ----------
吨
F
- 0100
-------------------------------------------------- ----------
吨
F
!readbools: 未能提取 'bool' 值。
- 0110
-------------------------------------------------- ----------
吨
F
吨
!readbools: 未能提取 'bool' 值。
- 0010
主要区别在于,这种方法在第三种情况下会产生 3 个成功读取的值,即使第三个值指定不正确(如"truex"
)。
即它无法识别这样的不正确规范。
当然,我编写 Code That Does Not Work™ 的能力并不能证明它不能工作。但是我相当擅长编写代码,并且我看不到任何方法来检测"truex"
不正确,使用这种方法(虽然使用基于读取单词异常的方法很容易做到)。所以至少对我来说,基于读取词异常的方法更简单,因为它很容易使其行为正确。