finish a file

J

Jim Langston

panig said:
how the program knows when a file is finsihed, mmm?

while ( mystream >> MyVar )
{
// process MyVar
}
mystream.close();

or
while (std::getline( mystream, mystring) )
{
// process mystring
}
mystream.close();
 
R

Roland Pibinger

while ( mystream >> MyVar )
{
// process MyVar
}
mystream.close();

or
while (std::getline( mystream, mystring) )
{
// process mystring
}
mystream.close();

After close() check the stream state. Otherwise you don't know "when a
file is finsihed".
 
J

Jim Langston

Roland Pibinger said:
After close() check the stream state. Otherwise you don't know "when a
file is finsihed".

Please explain this. After you call .close() don't we know that the file is
"finished"?
 
K

Kai-Uwe Bux

Roland said:
But when .close() fails?

Maybe, then you have an open but "finished" file. Could someone explain what
this "finished" term means. Is that an officially recognized state a file
can be in?


Best

Kai-Uwe Bux
 
K

Kai-Uwe Bux

Daniel said:
Can .close() fail? I think not.

The standard seems to allow close to fail [27.8.1.3/6]:

basic_filebuf<charT,traits>* close();

Effects: If is_open() == false, returns a null pointer. If a put area
exists, calls overflow(EOF) to flush characters. If the last virtual
member function called on *this (between underflow, overflow, seekoff,
and seekpos) was overflow then calls a_codecvt.unshift (possibly several
times) to determine a termination sequence, inserts those characters and
calls overflow(EOF) again. Finally it closes the file (??as if?? by
calling std::fclose(file)). If any of the calls to overflow or
std::fclose fails then close fails.

Returns: this on success, a null pointer otherwise.

Postcondition: is_open() == false.


Best

Kai-Uwe Bux
 
D

Daniel T.

Kai-Uwe Bux said:
Daniel said:
Can .close() fail? I think not.

The standard seems to allow close to fail [27.8.1.3/6]:

basic_filebuf<charT,traits>* close();

Effects: If is_open() == false, returns a null pointer. If a put area
exists, calls overflow(EOF) to flush characters. If the last virtual
member function called on *this (between underflow, overflow, seekoff,
and seekpos) was overflow then calls a_codecvt.unshift (possibly several
times) to determine a termination sequence, inserts those characters and

calls overflow(EOF) again. Finally it closes the file (??as if?? by
calling std::fclose(file)). If any of the calls to overflow or
std::fclose fails then close fails.

Returns: this on success, a null pointer otherwise.

Postcondition: is_open() == false.

So is_open() will subsequently and invariantly return false if close()
fails. Also, if close() returns a null pointer, that doesn't necessarily
mean that it failed (after all, it returns NULL if is_open() was false
on entry.

Quite a pickle. close() can "fail" but there is no way to know if it
actually did fail unless one first queries "is_open()". Also, if it does
fail, we are left with no options because despite that failure
"is_open()" will still equal false, and thus subsequent calls to close()
will continue to return NULL.

So what is the robust way to close a file?

if ( file.is_open() ) {
if ( file.close() == 0 ) {
// what do we do here? [A]
}
}

I guess in [A] above, we could try to re-open the file, if that failed
then the file object becomes useless and we are done with it, if it
succeeds, we can try to close it again. Then we are stuck alternating
between opening the file and closing it again until such time as either
open fails, or close succeeds. A rather non-deterministic problem, the
program could get locked in a infinite loop.


if ( file.is_open() ) {
while ( file.close == 0 ) {
file.open();
if ( ! file.is_open() ) {
break;
}
}
}

Something like that? :-(
 
R

Roland Pibinger

So what is the robust way to close a file?

if ( file.is_open() ) {
if ( file.close() == 0 ) {

..close() returns void
// what do we do here? [A]
}
}

What about:

file.close();
if (file.fail()) { // or file.bad()
// error
}

Better avoid iostreams for real work.

Best wishes,
Roland Pibinger
 
K

Kai-Uwe Bux

Daniel said:
Kai-Uwe Bux quoted the standard saying that close() returns either
'this' or NULL.

I quoted the close() method for the underlying buffer. The file stream has a
close() method, which calls the close() for the underlying buffer
[27.8.1.13/4]:

void close();
Effects: Calls rdbuf()->close() and, if that function returns false, calls
setstate(failbit)(27.4.4.3) (which may throw ios_base::failure).

As you can see, this one returns void but sets the failbit if it fails.

So which is it?

For the one from your code, void. Sorry for the confusion.


Best

Kai-Uwe Bux
 
D

Daniel T.

Kai-Uwe Bux said:
Daniel said:
Kai-Uwe Bux quoted the standard saying that close() returns either
'this' or NULL.

I quoted the close() method for the underlying buffer. The file stream has a
close() method, which calls the close() for the underlying buffer
[27.8.1.13/4]:

void close();
Effects: Calls rdbuf()->close() and, if that function returns false, calls
setstate(failbit)(27.4.4.3) (which may throw ios_base::failure).

As you can see, this one returns void but sets the failbit if it fails.

But the function doesn't return a bool it returns a pointer or NULL. So
by "returns false" I can only assume that they mean "returns NULL".
Except that doesn't work either because close() returns NULL if the file
wasn't initially opened, thus NULL doesn't mean a failure to close in
that case. Or is my snippet above in the fstream's close() function and
it sets failbit if the file was both open and close returned NULL?

I'm still left wondering, what is one supposed to do with a file if
close fails?
 
J

Jim Langston

Daniel T. said:
Kai-Uwe Bux said:
Daniel said:
(e-mail address removed) (Roland Pibinger) wrote:

On Wed, 15 Nov 2006 03:21:46 GMT, "Daniel T." wrote:
So what is the robust way to close a file?

if ( file.is_open() ) {
if ( file.close() == 0 ) {

.close() returns void

Kai-Uwe Bux quoted the standard saying that close() returns either
'this' or NULL.

I quoted the close() method for the underlying buffer. The file stream
has a
close() method, which calls the close() for the underlying buffer
[27.8.1.13/4]:

void close();
Effects: Calls rdbuf()->close() and, if that function returns false,
calls
setstate(failbit)(27.4.4.3) (which may throw ios_base::failure).

As you can see, this one returns void but sets the failbit if it fails.

But the function doesn't return a bool it returns a pointer or NULL. So
by "returns false" I can only assume that they mean "returns NULL".
Except that doesn't work either because close() returns NULL if the file
wasn't initially opened, thus NULL doesn't mean a failure to close in
that case. Or is my snippet above in the fstream's close() function and
it sets failbit if the file was both open and close returned NULL?

I'm still left wondering, what is one supposed to do with a file if
close fails?

I would think the only reason close would fail is if the file wasn't open in
the first place. And if it wasn't opened in the first place, then it is
closed. Consider close may fail in ths case:

std::ifstream MyFile( "Test.txt" );
if ( MyFile.is_open() )
{
// blah blah
}
MyFile.close();

If it wasn't able to open MyFile (it didn't exist, whatever) I presume that
the .close() would fail, but realisitcally, who cares? I already did a test
to see if it was open and if I needed something specific to do if it wasn't
found then I would have had an else. In practice it probably makes more
sense to put the .close() inside the if block, but I tend to put it outside
the block just like that, so I know when I'm done with a file without
looking inside blocks.

What does the standard say about the close() method itself, under what
conditions is it allowed to fail?
 

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,431
Messages
2,571,677
Members
48,796
Latest member
Greg L.

Latest Threads

Top