By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
424,835 Members | 1,959 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 424,835 IT Pros & Developers. It's quick & easy.

ifstream problems

P: n/a
Hi.

I ran across a bug in one of my problems and after spending some time
tracking it down i found that the problem arose in a piece of code that
essentially did this:

-----------
ifstream in("in.txt"); if(!in) {cout << "error\n";}
in.close(); if(!in) {cout << "error\n";}
in.close(); if(!in) {cout << "error\n";}

in.open("in.txt"); if(!in) {cout << "error\n";}
------------
It reports that opening the file on the last line was unsuccessful as
the last operation, the second in.close() causes an ifstream error.

After digging around in Stroustrups TC++PL i found that putting
'in.clear();' before the in.open() on the last line alleviates this
problem, but is this the right way of refreshing an ifstream that has
had a problem, or may I cause other problems by doing it in this way? Is
there another way I should do it?

regards
/hall
--
<- remove capital x:s from e-mail to reply ->

Jul 22 '05 #1
Share this Question
Share on Google+
4 Replies


P: n/a
hall wrote in news:iy********************@newsb.telia.net in comp.lang.c++:
Hi.

I ran across a bug in one of my problems and after spending some time
tracking it down i found that the problem arose in a piece of code that
essentially did this:

-----------
ifstream in("in.txt"); if(!in) {cout << "error\n";}
in.close(); if(!in) {cout << "error\n";}
You could prevent this from puting "in" into an error state with:

if ( in.is_open() )
in.close(); if(!in) {cout << "error\n";}
but a second call to close() isn't the only way "in" can become bad.

Also { in.close(); in.clear(); } is probably less expensive and
more Bullet Proof(tm) anyway.

in.open("in.txt"); if(!in) {cout << "error\n";}
------------
It reports that opening the file on the last line was unsuccessful as
the last operation, the second in.close() causes an ifstream error.

After digging around in Stroustrups TC++PL i found that putting
'in.clear();' before the in.open() on the last line alleviates this
problem, but is this the right way of refreshing an ifstream that has
had a problem, or may I cause other problems by doing it in this way?
Is there another way I should do it?


You should consider (if applicable):

int main()
{
// first:
{
ifstream in( "in.txt" );
// whatever
}

// second:
{
ifstream in( "in.txt" );
// different whatever

}
}

The above code reuses 'in' (well its storage anyway) without
all the faffing about, it lets the compiler do it instead.

In theory, your original method may be faster, but the real
cost is probably opening and closing the file, so it unlikly
that the difference can be measured.

If the above isn't applicable (and you can't make it so):

std::ifstream &reopen( std::ifstream &ifs, char const *name )
{
ifs.clear();

ifs.close();
ifs.clear();

ifs.open( name );

return ifs;
}

Rob.
--
http://www.victim-prime.dsl.pipex.com/
Jul 22 '05 #2

P: n/a
Rob Williscroft wrote:
hall wrote in news:iy********************@newsb.telia.net in comp.lang.c++:

Hi.

I ran across a bug in one of my problems and after spending some time
tracking it down i found that the problem arose in a piece of code that
essentially did this:

-----------
ifstream in("in.txt"); if(!in) {cout << "error\n";}
in.close(); if(!in) {cout << "error\n";}

You could prevent this from puting "in" into an error state with:

if ( in.is_open() )

in.close(); if(!in) {cout << "error\n";}

but a second call to close() isn't the only way "in" can become bad.


I am aware of this, and while I can prevent "in" from being closed twise
easily (as it is in a class for formatted output of data) I was more
worried of other causes that may make the ifstream turn bad, such as end
of file.

The class look something like (not tested code)

class Infile {
private:
std::ifstream in;
// ...
public:
void open(std::string s){ in.open(s) };
void close() { in.flush(); in.close() };
// ... methods for reading from file
};

As it is now, opening the ifstream may fail if a user previously have
made something to make the ifstream object to go bad, such as reading
untill end of file, trying to open a nonexisting file and so on.

Also { in.close(); in.clear(); } is probably less expensive and
more Bullet Proof(tm) anyway.

Would this then all be solved by changing the open() method into

void open(){ in.clear(std::string s); in.open(s)}

without giving any unpleasant suprises that i am not aware of (such as
that clear() doesn't fix the ifstream for all bad states)?

My only other idea for solving this was by turning "in" into an ifstream
pointer and create an instance in open() and delete it in close(), but i
thought it would just be too ugly and a better way must exist.


You should consider (if applicable):

int main()
{
// first:
{
ifstream in( "in.txt" );
// whatever
}

// second:
{
ifstream in( "in.txt" );
// different whatever

}
}

The above code reuses 'in' (well its storage anyway) without
all the faffing about, it lets the compiler do it instead.

This, the reusal of storage, i did not know. I'll keep it in mind for
the future, but for this class its not a good idea as i think it is to
be begging for errors to require anyone who uses the code to put each
Infile object in different scopes if he wants to reuse the object.
In theory, your original method may be faster, but the real
cost is probably opening and closing the file, so it unlikly
that the difference can be measured.

If the above isn't applicable (and you can't make it so):

std::ifstream &reopen( std::ifstream &ifs, char const *name )
{
ifs.clear();

ifs.close();
ifs.clear();

ifs.open( name );

return ifs;
}

Now this raises a question. Can I not close a file if
ifstream::good()=false ? Should I also change the close() function in my
class into
void close(){in.flush(); in.clear(); in.close()};
to make sure that the file is actually closed?
Rob.


regards
/hall
--
<- remove capital x:s from e-mail to reply ->

Jul 22 '05 #3

P: n/a
hall wrote in news:p0********************@newsb.telia.net in
comp.lang.c++:
Rob Williscroft wrote:
hall wrote in news:iy********************@newsb.telia.net in
comp.lang.c++:

Hi.

I ran across a bug in one of my problems and after spending some
time tracking it down i found that the problem arose in a piece of
code that essentially did this:

-----------
ifstream in("in.txt"); if(!in) {cout << "error\n";}
in.close(); if(!in) {cout << "error\n";}

You could prevent this from puting "in" into an error state with:

if ( in.is_open() )

in.close(); if(!in) {cout << "error\n";}

but a second call to close() isn't the only way "in" can become bad.


I am aware of this, and while I can prevent "in" from being closed
twise easily (as it is in a class for formatted output of data) I was
more worried of other causes that may make the ifstream turn bad, such
as end of file.

The class look something like (not tested code)

class Infile {
private:
std::ifstream in;
// ...
public:
void open(std::string s){ in.open(s) };
void close() { in.flush(); in.close() };
// ... methods for reading from file
};

As it is now, opening the ifstream may fail if a user previously have
made something to make the ifstream object to go bad, such as reading
untill end of file, trying to open a nonexisting file and so on.
>
Also { in.close(); in.clear(); } is probably less expensive and
more Bullet Proof(tm) anyway.
>


Would this then all be solved by changing the open() method into

void open(){ in.clear(std::string s); in.open(s)}


see below

without giving any unpleasant suprises that i am not aware of (such as
that clear() doesn't fix the ifstream for all bad states)?
It doesn't close the file, and open will fail, if the ifstream is
already open.

My only other idea for solving this was by turning "in" into an
ifstream pointer and create an instance in open() and delete it in
close(), but i thought it would just be too ugly and a better way must
exist.

Ugly dosn't matter, but that you then have to manage the liftime
of the new'd ifstream does, so in this case I'd go with the
close(), clear(), open() method.

[snip]

The above code reuses 'in' (well its storage anyway) without
all the faffing about, it lets the compiler do it instead.


This, the reusal of storage, i did not know. I'll keep it in mind for
the future, but for this class its not a good idea as i think it is to
be begging for errors to require anyone who uses the code to put each
Infile object in different scopes if he wants to reuse the object.
In theory, your original method may be faster, but the real
cost is probably opening and closing the file, so it unlikly
that the difference can be measured.

If the above isn't applicable (and you can't make it so):

std::ifstream &reopen( std::ifstream &ifs, char const *name )
{
ifs.clear();

ifs.close();
ifs.clear();

ifs.open( name );

return ifs;
}


Now this raises a question. Can I not close a file if
ifstream::good()=false ? Should I also change the close() function in
my class into


Yes according to the standard, you can (I just checked)
void close(){in.flush(); in.clear(); in.close()};
to make sure that the file is actually closed?


The flush() isn't needed, close() if indeed the ifstream is open
will do that for you:

void InFile::close()
{
in.close();
in.clear();
}

bool InFile::open( std::strinf const &s )
{
close(); /* InFile:: */
in.open( s.c_str() );
return in.good();
}

Rob.
--
http://www.victim-prime.dsl.pipex.com/
Jul 22 '05 #4

P: n/a

Thanks for your input!
and also, thanks for seeing through the misstakes I made while writing
the code examples. Guess I was a bit to tired last night ;-)

regards
/hall

--
<- remove capital x:s from e-mail to reply ->

Jul 22 '05 #5

This discussion thread is closed

Replies have been disabled for this discussion.