Michael Hoffmann
Michael Hoffmann

Reputation: 2436

Does ifstream::close reset failbit and/or badbit?

Does calling ifstream::close reset the stream's failbit and/or badbit, similar to calling clear? This is not a duplicate of this question- I need to know whether the flags are reset, not just when they're set.

For example, I'm using something like the following if-else in my current project:

ifstream myInputStream("foo.txt");

//Let's pretend this compiles all the time, even though it
//might not because the operator is ambiguous.
myInputStream << "Outputting to an input stream causes problems."

if (myInputStream.fail())
{
   cout << "Aw, nuts. It failed." << endl;
   myInputStream.close();
   return false;
}
else
{
   cout << "No nuts here. Only chocolate chips." << endl;
   myInputStream.close();
   return true;
}

Do I have to have the call to myInputStream.close after the call to myInputStream.fail, in each branch, to get an accurate check? Or will this work:

ifstream myInputStream("foo.txt");

myInputStream << "Outputting to an input stream causes problems.";    

myInputStream.close();

if (myInputStream.fail())
{
   cout << "Aw, nuts. It failed." << endl;
   return false;
}
else
{
   cout << "No nuts here. Only chocolate chips." << endl;
   return true;
}

I know that ifstream::close can itself set failbit or badbit if closing fails, which is one reason I want to call it before checking for failure- I need to return false regardless of what caused it. It also looks less cluttered if the closure is only done once.

tl;dr;

Does ifstream::close reset failbit or badbit if something else has already set it, making my second code sample return true?

Upvotes: 2

Views: 2153

Answers (2)

Michael Hoffmann
Michael Hoffmann

Reputation: 2436

Using the example code in the question (modified so it compiles with g++), it looks like ifstream::close does not reset failbit. I don't know about badbit, however (ios::fail returns true if either is set).

#include <fstream>
#include <iostream>
using namespace std;

int main()
{
   ofstream writer("foo.txt");

   writer << "These are not integers.";

   writer.close();

   ifstream myInputStream("foo.txt");

   int i;
   myInputStream >> i;//This should set the failbit.

   myInputStream.close();//Will this reset it?

   if (myInputStream.fail())
   {
      cout << "Aw, nuts. It failed." << endl;
      return false;
   }
   else
   {
      cout << "No nuts here. Only chocolate chips." << endl;
      return true;
   }
}

Output: Aw, nuts. It failed.

myInputStream.fail() is returning false.

Upvotes: 1

user657267
user657267

Reputation: 21000

close() should not clear any of the state flags, although it might set failbit depending on the return value of the underlying buffer.

[fstream.members] (also [ifstream.members] and [ofstream.members])

void close();

Effects: Calls rdbuf()->close() and, if that function returns returns a null pointer, calls setstate(failbit) (27.5.5.4) (which may throw ios_base::failure).

The flags are cleared by open() however, assuming the filebuf opens correctly

void open(const char* s, ios_base::openmode mode = ios_base::in|ios_base::out);

Effects: Calls rdbuf()->open(s,mode). If that function does not return a null pointer calls clear(), otherwise calls setstate(failbit), (which may throw ios_base::failure) (27.5.5.4).

Upvotes: 5

Related Questions