Thread: Help me with eof

  1. #1
    Registered User
    Join Date
    May 2008
    Posts
    134

    Help me with eof

    this is my code:

    Code:
    #include<iostream>
    #include<fstream>
    
    using namespace std;
    
    void readChar(ifstream &inSFile);
    
    int main()      {
    
    ifstream in("in.txt");
    readChar(in);
    }
    
    void readChar(ifstream &inSFile)        {
            char ch;
            do{
                    while(inSFile.get(ch))  {
                            cout << ch;
                            if(ch=='\n')    {
                                    break;
                            }
                    }
                    cout << "got a new line"<<endl;
            } while(ch == '\n' && !inSFile.eof());
    }
    this is my in.txt:
    Code:
    666666
    7777777
    88888888
    Output:
    Code:
    666666
    got a new line
    7777777
    got a new line
    88888888
    got a new line
    got a new line
    The last line "got a new line" is unexpected, how can I fix it?

  2. #2
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,660
    By only using one while loop perhaps?

    Also, you read a character WITHOUT testing for eof, then go ahead and do something anyway.
    Most likely, ch still contains the previous input.

    while ( inSFile.get(ch) )
    reads the whole file, and exits when it hits eof.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  3. #3
    Registered User
    Join Date
    May 2008
    Posts
    134
    I use two loops just because I wanted to process each line each time,

    as you said I am reading character without testing for eof, in such case,
    It won't enter into
    Code:
    while(inSFile.get(ch)) {
    //loop
    }
    As you said it exits when it hits eof, why in this case it is going through an extra loop even if the file ends, is there any way to stop this extra iteration?

  4. #4
    Registered User
    Join Date
    May 2008
    Posts
    87
    Quote Originally Posted by kapil1089thekin View Post
    as you said I am reading character without testing for eof, in such case,
    It won't enter into
    Code:
    while(inSFile.get(ch)) {
    //loop
    }
    This is not true. I suspect you are thinking that get() returns an integer which will correspond to the character read, or some negative value in the case of EOF. However, the return value of get(char& c) is a reference back to the stream. If you want the version that returns an integer, you have to do
    Code:
    ch = inSFile.get(); // Returns integer
    get - C++ Reference

    Edit: And if it isn't clear, ch should be of type int if it is going to be able to handle EOF.

  5. #5
    Registered User
    Join Date
    May 2008
    Posts
    134
    Do I need to use:
    Code:
     while (is.good())  {
    //code
    }
    ????

  6. #6
    Registered User
    Join Date
    May 2008
    Posts
    87
    Yes, you could follow what the example in that link did. I don't like it as much because it needs to check for EOF twice. You can make it more compact while still being readable IMO. Perhaps something like (taking advantage of the fact that istream.get(char& c) returns a reference to itself):
    Code:
    char ch;
    while (inSFile.get(ch).good()) {
      // code; ch will hold the character read
    }

  7. #7
    Lurking whiteflags's Avatar
    Join Date
    Apr 2006
    Location
    United States
    Posts
    9,613
    Yes, you could follow what the example in that link did. I don't like it as much because it needs to check for EOF twice.
    Does it? There should be no difference.

    Code:
        std::ifstream file;
        std::string path;
        std::getline (std::cin , path);
        file.open (path.c_str ());
        if (file.is_open ()) {
            char c;
            c = file.get (); // primary read
            while (file) {
                std::cout.put (c);
                c = file.get (); // driving read
            }
            file.close ();
        }
    Perhaps the original source forgot something.

  8. #8
    Registered User
    Join Date
    May 2010
    Posts
    4,633
    How about as Salem suggested:

    Code:
    void readChar(ifstream &inSFile) {
       char ch;
       while(inSFile.get(ch))  {
          cout << ch;
          if(ch=='\n')    {
             cout << "got a new line"<<endl;
           }
       }
    }

  9. #9
    Registered User
    Join Date
    May 2008
    Posts
    87
    Ah, I didn't realize the while condition would evaluate to false when EOF was encountered.

    I'm curious though about ch being of type char. get() returns an int, so I was expecting that g++ with -Wall was going to warn me about possible loss of data? But it compiled without any warnings.

    The code I was referring to from the link I posted is:

    Code:
    // istream get
    #include <iostream>
    #include <fstream>
    using namespace std;
    
    int main () {
      char c, str[256];
      ifstream is;
    
      cout << "Enter the name of an existing text file: ";
      cin.get (str,256);
    
      is.open (str);        // open file
    
      while (is.good())     // loop while extraction from file is possible
      {
        c = is.get();       // get character from file
        if (is.good())
          cout << c;
      }
    
      is.close();           // close file
    
      return 0;
    }

  10. #10
    Registered User
    Join Date
    May 2008
    Posts
    87
    Quote Originally Posted by jimblumberg View Post
    How about as Salem suggested:

    Code:
    void readChar(ifstream &inSFile) {
       char ch;
       while(inSFile.get(ch))  {
          cout << ch;
          if(ch=='\n')    {
             cout << "got a new line"<<endl;
           }
       }
    }
    Yeah, knowing what I now do about the stream evaluating to false when EOF is encountered, I agree this is probably the nicest approach. Cleaner looking that "while(inSFile.get(ch).good())" and does the same thing.

  11. #11
    Lurking whiteflags's Avatar
    Join Date
    Apr 2006
    Location
    United States
    Posts
    9,613
    Honestly, I prefer Salem's as well, but as I pointed out, you can write the original source so it doesn't check the stream twice. It turns out it did forget to do a primary read, so the double check was required.

  12. #12
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    Quote Originally Posted by jason_m View Post
    I'm curious though about ch being of type char. get() returns an int, so I was expecting that g++ with -Wall was going to warn me about possible loss of data? But it compiled without any warnings.
    Afaik, GCC doesn't emit narrowing warnings.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. while ((c = getchar()) != EOF), AND cntrl z
    By Roger in forum C Programming
    Replies: 8
    Last Post: 10-21-2009, 09:25 PM
  2. EOF Explanation Anybody?
    By blackcell in forum C Programming
    Replies: 1
    Last Post: 01-29-2008, 09:09 PM
  3. EOF or not EOF?
    By CornedBee in forum Linux Programming
    Replies: 2
    Last Post: 09-14-2007, 02:25 PM
  4. EOF messing up my input stream?
    By Decrypt in forum C++ Programming
    Replies: 4
    Last Post: 09-30-2005, 03:00 PM
  5. files won't stop being read!!!
    By jverkoey in forum C++ Programming
    Replies: 15
    Last Post: 04-10-2003, 05:28 AM