exception woes using fstream and .eof

Discussion in 'C++' started by Greg, Dec 18, 2005.

  1. Greg

    Greg Guest

    I am trying to convert an older console application written in C to a
    visual application using several Borland VCL components (open and save
    dialogs). I am declaring input and output stream variables as follows:


    ifstream InputFile;
    ofstream OutputFile;

    I am initializing them using the filename properties in the "open" and
    "save" dialogs respectively, with the "._C_str" modifier attached to
    the end. The files to be read are comma separated variable type with
    5000 to 30000 data pairs. I was trying to use "InputFile.getline(line,
    81)", but when I use it in the following while loop, I get runtime
    exception errors that look like language exceptions:

    while( ! InputFile.eof ( ))

    {

    InputFile.getline(line, 81);

    and more stuff;

    }

    Two additional notes: 1) I can continue to run the program after the
    exception dialog is closed, and the output file appears fine, and 2) If
    I replace the while loop with a for loop, I don't get exceptions.
    However, I'd rather use the while loop (much neater for my application)
    Any help would be appreciated.

    Thanks in advance.
     
    Greg, Dec 18, 2005
    #1
    1. Advertising

  2. Greg wrote:
    > while( ! InputFile.eof ( ))
    >
    > {
    >
    > InputFile.getline(line, 81);
    >
    > and more stuff;
    >
    > }


    If is always wrong not to check the success of an input function: the
    library cannot know in advance what you want to read next. Thus, you
    should test the read operation for success. In addition, I propose
    that you don't use a fixed length string to deal with lines but rather
    string object. Your loop should thus rather look something like this:

    for (std::string line; std::getlin(InputFile, line); )
    /* process your line */;
    --
    <mailto:> <http://www.dietmar-kuehl.de/>
    <http://www.eai-systems.com> - Efficient Artificial Intelligence
     
    Dietmar Kuehl, Dec 18, 2005
    #2
    1. Advertising

  3. Greg

    Greg Guest

    Please forgive my ignorance, but I'm still struggling with many aspects
    of ANSI/ISO Standard C++ . I have several questions: (1) I have a
    "using namespace std" statement below my preprocessor directives ( #
    include <...>). Does that mean I don't have to use the "std::" prefix?
    (2) What's the difference between "std::getline( )" and, in my
    particular case: "InputFile.getline( )" ? (3) Should I use something
    like: "if (InputFile.getline( )) { do some stuff with the string }" to
    check the success of the input function? (4) Is using the ".eof ( )"
    function not as straightforward as it appears? Isn't it a boolean
    function that takes no input parameters? In my particular case, I'm
    using "InputFile.eof( )" Thanks again for your assistance.
     
    Greg, Dec 18, 2005
    #3
  4. Greg

    Heinz Ozwirk Guest

    "Greg" <> schrieb im Newsbeitrag
    news:...
    > Please forgive my ignorance, but I'm still struggling with many aspects
    > of ANSI/ISO Standard C++ . I have several questions: (1) I have a
    > "using namespace std" statement below my preprocessor directives ( #
    > include <...>). Does that mean I don't have to use the "std::" prefix?


    You shuld better not use "using namespace std". You might get much more than
    you want. Get used to the std:: prefix.

    > (2) What's the difference between "std::getline( )" and, in my
    > particular case: "InputFile.getline( )" ?


    std::getline can read an std::string. ifstream's getline member cannot.

    > (3) Should I use something
    > like: "if (InputFile.getline( )) { do some stuff with the string }" to
    > check the success of the input function?


    As Dietmar suggested, use something like for(...; std::getline(...); ...) or
    while (std::getline(...))

    > (4) Is using the ".eof ( )"
    > function not as straightforward as it appears? Isn't it a boolean
    > function that takes no input parameters? In my particular case, I'm
    > using "InputFile.eof( )" Thanks again for your assistance.


    eof is used after reading from a file, to determine whether reading has been
    successfull or not. You cannot use eof to predict the result of the next
    input operation. But I cannot remmber when I actually did use eof.
    std::getline returns (something like) true on success and false on error
    (including the end of the file). If you are interested in why reading
    stopped, you can use eof, but do you really care?

    HTH
    Heinz
     
    Heinz Ozwirk, Dec 18, 2005
    #4
  5. Greg wrote:

    > Please forgive my ignorance, but I'm still struggling with many aspects
    > of ANSI/ISO Standard C++ .


    > I have several questions: (1) I have a
    > "using namespace std" statement below my preprocessor directives ( #
    > include <...>). Does that mean I don't have to use the "std::" prefix?


    Basically, yes. It brings all the symbols that are contained
    in std:: to the global namespace. Make sure, however, that you
    don't use 'using namespace std' in header files, only in
    source files.


    > (2) What's the difference between "std::getline( )" and, in my
    > particular case: "InputFile.getline( )" ?


    The first gets the line into a std::string, the latter into
    a char[] array. Therefore the first one doesn't rely on the
    line being 'short enough' to fit your fixed-size char[] array.
    std::string can grow to accomodate data.

    > (4) Is using the ".eof ( )"
    > function not as straightforward as it appears?


    It is not.

    > Isn't it a boolean
    > function that takes no input parameters? In my particular case, I'm
    > using "InputFile.eof( )"


    Yes it is.

    The trouble with .eof() is that you can't reliably tell
    if a stream is at EOF *before* you try to read the last
    datum. For instance someone can append data to the stream in
    the meantime, or if the stream is tied to the keyboard it's
    hard to tell EOF at all. For a longer explanation try

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

    Perhaps you could catch the exception and see what it is?

    #include<exception>
    try {
    // getline stuff
    }
    catch(exception &e) {
    cerr "Shit has just happened: " << e.what() << endl;
    }

    HTH,
    - J.
     
    Jacek Dziedzic, Dec 18, 2005
    #5
  6. Greg wrote:
    > (1) I have a
    > "using namespace std" statement below my preprocessor directives ( #
    > include <...>). Does that mean I don't have to use the "std::" prefix?


    I'm no fan of using directives. I even only use using declarations
    where I really have to. I prefer the explicit qualification, possibly
    with a namespace alias for a short hand (of, course hardly for 'std'
    as this is about a short as it gets). It makes it easier to tell where
    a particular class or functions comes from.

    However, yes, a using directive means that you don't have to use the
    explicit scope qualification, i.e. you can omit the 'std::' if you
    want to.

    > (2) What's the difference between "std::getline( )" and, in my
    > particular case: "InputFile.getline( )" ?


    The function 'std::getline()' operates on 'std::string' objects (well,
    it is actually a function template operating on 'std::basic_string'
    instantiations but unless you are dealing with templates it is
    probably sufficient to know that it operates on 'std:string') while
    the member function 'std::istream::getline()' operates on character
    arrays. 'std::string' has several advantages, one being that it can
    cope with variable sized strings meaning that your lines effectively
    become unlimited (there is a limit but it is generally rather large;
    see 'std::string::max_size()' for the limit). I wouldn't advice people
    new to C++ to use built-in arrays. The various classes like
    'std::string', 'std::vector', etc. have many advantages.

    > (3) Should I use something
    > like: "if (InputFile.getline( )) { do some stuff with the string }" to
    > check the success of the input function?


    No. You should use 'std::string's to operate on and check the result
    of the corresponding stream: the stream functions return the stream they
    operate on and there is a conversion to a Boolean state which indicates
    whether the stream ran into an error. That is, you should use something
    like

    if (std::getline(InputFile, str)) { do some stuff with the string }

    Hm, somehow I have the strange feeling I advised you to do so in the
    previous article...

    > (4) Is using the ".eof ( )" function not as straightforward as it
    > appears?


    Obviously... The only reasonable use for the member 'eof()' is to
    determine whether input failed due to a format error or due to hitting
    end of file. The former is generally an error which needs some form of
    handling, e.g. informing the user that the input format was broken,
    whereas the latter often just indicates that all input was read and
    signals that you need to go on doing other stuff. It is only of minor
    use when you want to tell whether the next input could be successful:
    You know that it will fail for sure if the bit is set but it could
    fail, too, if the bit is not set, e.g. because there is no more input.

    > Isn't it a boolean function that takes no input parameters?


    Right. But the interpretation of the function's result is not as
    simple as many people think it is. As a said before: the stream cannot
    tell in advance what you want to read. Thus, you need to check your
    results *after* you have tried to read something. This is actually a
    statement applying to many more I/O libraries than just the C++
    standard library.

    > In my particular case, I'm using "InputFile.eof( )"


    I have seen that you were using it. ...and the way you use it is
    entirely inappropriate - as I already stated [implicitly] in my
    previous reply. A reasonable use of 'eof()' would look like this:

    int i = 0;
    if (!(std::cin >> i))
    if (std::cin.eof())
    std::cout << "OK, I'm done reading\n";
    else
    std::cout << "ERROR: expected to read an integer!\n";

    Maybe it is worth to at least consider the advice you get from the
    net, especially when you ask for it! What is the point of asking
    otherwise?
    --
    <mailto:> <http://www.dietmar-kuehl.de/>
    <http://www.eai-systems.com> - Efficient Artificial Intelligence
     
    Dietmar Kuehl, Dec 18, 2005
    #6
  7. Greg

    Greg Guest

    Thanks very much for all of the advice.....It may take me a few hours,
    days, or weeks to digest it all. As I said before, please forgive my
    ignorance of the C++ language. I'll try to form some coherent comments
    and questions, and reply again in a few hours. And again, thanks for
    everyones' patience and generous information.
     
    Greg, Dec 18, 2005
    #7
  8. Greg

    Default User Guest

    Greg wrote:

    > Please forgive my ignorance, but I'm still struggling with many
    > aspects of ANSI/ISO Standard C++


    You are also struggling with how to post properly. Read my .sig below
    for important information.



    Brian

    --
    Please quote enough of the previous message for context. To do so from
    Google, click "show options" and use the Reply shown in the expanded
    header.
     
    Default User, Dec 19, 2005
    #8
    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. Armando
    Replies:
    6
    Views:
    778
    Armando
    Jan 29, 2004
  2. kartik
    Replies:
    1
    Views:
    569
    Jack Klein
    Oct 30, 2004
  3. Kobu
    Replies:
    10
    Views:
    667
    Keith Thompson
    Mar 4, 2005
  4. SpreadTooThin

    ifstream eof not reporting eof?

    SpreadTooThin, Jun 13, 2007, in forum: C++
    Replies:
    10
    Views:
    722
    James Kanze
    Jun 15, 2007
  5. David
    Replies:
    2
    Views:
    615
    Kumar Anurag
    Feb 11, 2010
Loading...

Share This Page