Ответ 1
Очень легко различать EOF и другие ошибки, если вы не настраиваете поток для использования исключений.
Просто проверьте stream.eof()
в конце.
До этого проверяйте только отказ/отказ, например. stream.fail()
или !stream
. Обратите внимание, что good
не является противоположностью fail
. Поэтому вообще не смотрите на good
, только на fail
.
Edit:
Пример кода примера, а именно ваш пример, измененный для отличия спецификации ungood 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" );
}
Результат:
------------------------------------------------------------ T F - 0110 ------------------------------------------------------------ T F !boolFrom: failed to extract 'bool' value. - 0110 ------------------------------------------------------------ T F !boolFrom: found extra characters at end. - 0110
Изменить 2: в опубликованном коде и результатах добавлен пример использования проверки eof()
, которую я забыл.
Изменить 3: В следующем соответствующем примере используется предлагаемое OP-rsquo решение для пропуска-пробела перед чтением:
#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: failed to extract 'bool' value. - 0110 ------------------------------------------------------------ T F T !readbools: failed to extract 'bool' value. - 0010
Основное отличие состоит в том, что этот подход дает 3 успешно прочитанных значения в третьем случае, даже если третье значение указано неправильно (как "truex"
).
т.е. он не может распознать неправильную спецификацию как таковую.
Конечно, моя способность писать код, который не работает и торгует; не является доказательством того, что он не может работать. Но я довольно хорошо разбираюсь в вещах, и я не мог обнаружить никакого способа обнаружить "truex"
как некорректный, с таким подходом (хотя это было легко сделать с использованием подхода, основанного на исключении чтения-слова). Поэтому, по крайней мере, для меня подход на основе исключений, основанных на чтении слов, проще, в том смысле, что легко заставить его вести себя правильно.
Приветствия и hth.,