I/O exceptions

A

Amadeus W. M.

I'm trying to read a vector from a file, while checking the correctness of
the input. I do this by setting the failbit.

double tmp;
vector<double> x;
fstream IN(argv[1], ios::in);

IN.exceptions(std::ios_base::failbit);
try{
while(IN>>tmp)
x.push_back(tmp);
}
catch(...){

}

But that's not right, because when IN reads the EOF an exception is raised.
I only want to catch the potential input errors other than the EOF.
What's the right way to do this?

Thanks.
 
M

Mike Wahler

Amadeus W. M. said:
I'm trying to read a vector from a file, while checking the correctness of
the input. I do this by setting the failbit.

double tmp;
vector<double> x;
fstream IN(argv[1], ios::in);

IN.exceptions(std::ios_base::failbit);
try{
while(IN>>tmp)
x.push_back(tmp);
}
catch(...){

}

But that's not right, because when IN reads the EOF an exception is
raised.

That's because in this case reaching end of file sets not only eofbit, but
failbit as well (the last conversion failed).
I only want to catch the potential input errors other than the EOF.
What's the right way to do this?

IN.exceptions(0);

while(IN >> tmp)
x.push_back(tmp);

if(!IN.eof())
std::cerr << "Error\n";

-Mike
 
M

mlimber

Amadeus said:
I'm trying to read a vector from a file, while checking the correctness of
the input. I do this by setting the failbit.

double tmp;
vector<double> x;
fstream IN(argv[1], ios::in);

IN.exceptions(std::ios_base::failbit);
try{
while(IN>>tmp)
x.push_back(tmp);
}
catch(...){

}

But that's not right, because when IN reads the EOF an exception is raised.
I only want to catch the potential input errors other than the EOF.
What's the right way to do this?

Thanks.

IIRC, the failbit indicates that the *next* extraction operation on the
ifstream will fail, and if the EOF is found, the next extraction must
fail. Perhaps a more standard way to do it would be:

ifstream in( "somefile.txt" );
vector<double> v;

double d;
while( in >> d )
v.push_back( d );
//or
//
//copy( istream_iterator<double>( in ),
// istream_iterator<double>(),
// back_inserter( v ) );

if( in.bad() || !in.eof() )
{
// Some error occurred
}

If you really want to use exceptions, you catch block could look
something like:

catch( const exception& e )
{
if( in.bad() || !in.eof() )
{
// Some error occurred
}
}

Cheers! --M
 
D

deane_gavin

mlimber said:
Amadeus said:
I'm trying to read a vector from a file, while checking the correctness of
the input. I do this by setting the failbit.

double tmp;
vector<double> x;
fstream IN(argv[1], ios::in);

IN.exceptions(std::ios_base::failbit);
try{
while(IN>>tmp)
x.push_back(tmp);
}
catch(...){

}

But that's not right, because when IN reads the EOF an exception is raised.
I only want to catch the potential input errors other than the EOF.
What's the right way to do this?

Thanks.

IIRC, the failbit indicates that the *next* extraction operation on the
ifstream will fail, and if the EOF is found, the next extraction must
fail. Perhaps a more standard way to do it would be:

ifstream in( "somefile.txt" );
vector<double> v;

double d;
while( in >> d )
v.push_back( d );
//or
//
//copy( istream_iterator<double>( in ),
// istream_iterator<double>(),
// back_inserter( v ) );

if( in.bad() || !in.eof() )
{
// Some error occurred
}

I think calling bad() here is redundant. You have got to this point
because reading stopped. If all you care about is whether some error
occurred then all you need to check is eof because if no error occurred
the only other reason reading would have stopped is eof.

Gavin Deane
 
A

Amadeus W. M.

I'm trying to read a vector from a file, while checking the correctness of
the input. I do this by setting the failbit.

double tmp;
vector<double> x;
fstream IN(argv[1], ios::in);

IN.exceptions(std::ios_base::failbit);
try{
while(IN>>tmp)
x.push_back(tmp);
}
catch(...){

}

But that's not right, because when IN reads the EOF an exception is raised.
I only want to catch the potential input errors other than the EOF.
What's the right way to do this?

Thanks.

Thank you all for the suggestions, I don't know what I was thinking.
This is what I had in mind, but I could not spell out until after reading
this thread:

template <class T>
istream & operator>>(istream & IN, vector<T> & x)
{
T tmp;
while(IN>>tmp)
x.push_back(tmp);

if(!IN.eof())
throw string("Bad input.");

return IN;
}

then in main(), a simple

try{
cin >> x;
}
catch(string & err){
cerr << err << endl;
// handle the error
}
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
474,432
Messages
2,571,680
Members
48,796
Latest member
Greg L.

Latest Threads

Top