File stream close followed by open leads to inconsistent behavior

  • Thread starter Generic Usenet Account
  • Start date
G

Generic Usenet Account

I have been able to recreate a problem that I am having with the file
stream using the simple sample code given below.

I am trying to read the number of lines in a file, relying on the
getline method to read all the characters (including leading
whitespaces) until the new line character (the default line delimiter)
or end-of-file is reached. Then I close the stream, reopen it and
repeat the procedure. I get the correct answer only the first time.
The second time I get value of zero. This is with gcc version 3.3.1

Is this a compiler issue, or is this standard language feature?

Sample code follow

Thanks,
Song

///////////////////////////////////////////////////////////////////////
#include <iostream>
#include <fstream>
#include <stdlib.h>
#include <string>

using namespace std;

main(int argc, char* argv[])
{
if(argc < 2)
{
cerr << "usage: " << argv[0] << " <filename>" << endl;
exit(-1);
}

ifstream fileStrm(argv[1]);
if(!fileStrm)
{
cerr << "Cannot open file " << argv[1] << " ....aborting" << endl;
exit (-2);
}

// First pass
string token;
unsigned long nlCount = 0;
while(getline(fileStrm, token))
nlCount++;
fileStrm.close();
cout << nlCount << "\n";

// Second pass
fileStrm.open(argv[1]);
nlCount = 0;
while(getline(fileStrm, token))
nlCount++;
fileStrm.close();
cout << nlCount << "\n";

exit(0);
}
 
V

Victor Bazarov

Generic said:
I have been able to recreate a problem that I am having with the file
stream using the simple sample code given below.

I am trying to read the number of lines in a file, relying on the
getline method to read all the characters (including leading
whitespaces) until the new line character (the default line delimiter)
or end-of-file is reached. Then I close the stream, reopen it and
repeat the procedure. I get the correct answer only the first time.
The second time I get value of zero. This is with gcc version 3.3.1

Is this a compiler issue, or is this standard language feature?

I would call it a bug in your program...
Sample code follow

Thanks,
Song

///////////////////////////////////////////////////////////////////////
#include <iostream>
#include <fstream>
#include <stdlib.h>
#include <string>

using namespace std;

main(int argc, char* argv[])

int main(int argc, char* argv[])
{
if(argc < 2)
{
cerr << "usage: " << argv[0] << " <filename>" << endl;
exit(-1);
}

ifstream fileStrm(argv[1]);
if(!fileStrm)
{
cerr << "Cannot open file " << argv[1] << " ....aborting" << endl;
exit (-2);
}

// First pass
string token;
unsigned long nlCount = 0;
while(getline(fileStrm, token))
nlCount++;


At this point 'fileStrm' is in bad state - end of file. Calling 'close'
does not change that.
fileStrm.close();
cout << nlCount << "\n";

// Second pass

You might want to begin with

fileStrm.clear();
fileStrm.open(argv[1]);
nlCount = 0;
while(getline(fileStrm, token))
nlCount++;
fileStrm.close();
cout << nlCount << "\n";

exit(0);
}


V
 
M

masood.iqbal

Generic said:
Sample code follow

ifstream fileStrm(argv[1]);
if(!fileStrm)
{
cerr << "Cannot open file " << argv[1] << " ....aborting" << endl;
exit (-2);
}


Can someone please explain to me how instantiation of the input file
stream object can return a NULL? Sometime back I tried a similar
approach on a user-defined class. In the constructor I tried to set
the "this" pointer to NULL in case of an error. The intent was to
check for a NULL object at the point of invocation, in much the same
way as shown above. However, the compiler did not allow me to do that.
Furthermore, I was told by a C++ Guru that the way to handle errors in
object instantiation is to throw an exception.

How in the world do we then get away with returning a NULL object in
the case of an error in this case?

Thanks,
Masood
 
V

Victor Bazarov

Generic said:
Sample code follow

ifstream fileStrm(argv[1]);
if(!fileStrm)
{
cerr << "Cannot open file " << argv[1] << " ....aborting" <<
endl; exit (-2);
}


Can someone please explain to me how instantiation of the input file
stream object can return a NULL? Sometime back I tried a similar
approach on a user-defined class. In the constructor I tried to set
the "this" pointer to NULL in case of an error. The intent was to
check for a NULL object at the point of invocation, in much the same
way as shown above. However, the compiler did not allow me to do
that. Furthermore, I was told by a C++ Guru that the way to handle
errors in object instantiation is to throw an exception.

How in the world do we then get away with returning a NULL object in
the case of an error in this case?

'std::basic_ios' (the base class for all streams) has an overloaded
operator void*, which returns a null pointer if 'fail()' returns true.

V
 
M

Marcus Kwok

D

David Harmon

On Tue, 15 Aug 2006 15:51:36 -0400 in comp.lang.c++, "Victor
Bazarov said:
At this point 'fileStrm' is in bad state - end of file. Calling 'close'
does not change that.

Rather, a failed state. eofbit and failbit are set, not badbit.
 

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

Forum statistics

Threads
473,774
Messages
2,569,596
Members
45,142
Latest member
arinsharma
Top