File stream close followed by open leads to inconsistent behavior

Discussion in 'C++' started by Generic Usenet Account, Aug 15, 2006.

  1. 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);
    }
    Generic Usenet Account, Aug 15, 2006
    #1
    1. Advertising

  2. Generic Usenet Account wrote:
    > 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
    --
    Please remove capital 'A's when replying by e-mail
    I do not respond to top-posted replies, please don't ask
    Victor Bazarov, Aug 15, 2006
    #2
    1. Advertising

  3. Generic Usenet Account

    Guest

    Generic Usenet Account wrote:
    > 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
    , Aug 16, 2006
    #3
  4. wrote:
    > Generic Usenet Account wrote:
    >> 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
    --
    Please remove capital 'A's when replying by e-mail
    I do not respond to top-posted replies, please don't ask
    Victor Bazarov, Aug 16, 2006
    #4
  5. Generic Usenet Account

    Marcus Kwok Guest

    In comp.lang.c++ wrote:
    > Generic Usenet Account wrote:
    >> 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?


    This answer in the FAQ is about the "while (std::cin >> foo)" syntax,
    but its explanation applies also to std::ifstream:

    http://www.parashift.com/c -faq-lite/input-output.html#faq-15.4

    --
    Marcus Kwok
    Replace 'invalid' with 'net' to reply
    Marcus Kwok, Aug 16, 2006
    #5
  6. Generic Usenet Account

    David Harmon Guest

    On Tue, 15 Aug 2006 15:51:36 -0400 in comp.lang.c++, "Victor
    Bazarov" <> wrote,
    >> while(getline(fileStrm, token))
    >> nlCount++;

    >
    >
    >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.
    David Harmon, Aug 16, 2006
    #6
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Replies:
    1
    Views:
    346
    Roedy Green
    Aug 12, 2005
  2. Replies:
    6
    Views:
    442
    ExGuardianReader
    Aug 14, 2005
  3. Xiao Ma
    Replies:
    16
    Views:
    1,407
    =?ISO-8859-15?Q?Arne_Vajh=F8j?=
    Oct 27, 2007
  4. Iñaki Baz Castillo
    Replies:
    7
    Views:
    822
    Iñaki Baz Castillo
    Jan 12, 2010
  5. Iulian Ilea
    Replies:
    1
    Views:
    293
    pcx99
    Dec 21, 2006
Loading...

Share This Page