ifstream: check if opened successfully
A colleague just told me that this code:
std::ifstream stream(filename.c_str());
if (!stream)
{
throw std::runtime_error("..");
}
would be wrong. He said ifstream
evaluates to 0 if opening is successful. My code works, but I wanted to find the doc开发者_StackOverflow中文版umentation but didn't see where it says how to check if opening was successful. Can you point me to it?
operator!
is overloaded for std::ifstream
, so you can do this.
In my opinion, though, this is a horrible abuse of operator overloading (by the standards committee). It's much more explicit what you're checking if you just do if (stream.fail())
.
You can make a particular stream throw an exception on any of eof/fail/bad by calling its ios::exceptions() function with the proper bitmask. So, you could rewrite the example in the initial question above as:
std::ifstream stream;
stream.exceptions(std::ios::failbit | std::ios::badbit);
stream.open(filename.c_str());
Here stream will throw an exception when the failbit or badbit gets set. For example if ifstream::open() fails it will set the failbit and throw an exception. Of course, this will throw an exception later if either of these bits gets set on the stream, so this rewrite is not exactly the same as the initial example. You can call
stream.exceptions(std::ios::goodbit);
to cancel all exceptions on the stream and go back to checking for errors.
You can also use is_open() to check if it worked, but ! is allowed (it's not checking for zero, it's a special overload of ! )
edit:
Just out of interest - why doesn't this throw an exception?
Is it just that streams were introduced before exceptions
or are we into the old C++ thing of - it's only an error not exceptional enough to be an exception.
Your colleague is wrong. Perhaps he's forgotten that you're not writing C.
The code is spot on. It's exactly how you should be checking stream state.
精彩评论