Thread: How do I know if I am at the end of a file (and other FILEIO Qs?

  1. #1
    System.out.println("");
    Join Date
    Jan 2005
    Posts
    84

    How do I know if I am at the end of a file (and other FILEIO Qs?

    I am trying one of the challenges offered on the website for counting the number of lines in a file. How can I tell when I am through reading a file? Basically I don't really know how so I ran a little test. I created a text file with lines (numbers) in it and read 5 lines and printed out what was read after each step. Well, what I discovered was that if it doesn't read anything the value never changes. This isn't very helpful as checking if it's the same before and after reading each line doesn't necessarily tell you if you are done because if two lines are the same then the result would be the same even though you aren't at the end of the line. Anyway, that was my thought process and here's my code.
    Thanks in advance.

    Code:
    #include <iostream>
    #include <fstream>
    
    using namespace std;
    
    int test;
    int main()
    {
       ifstream in ("input.txt");
       //read the line and then print it out so I can see what's 
       //been read.
       in>>test;
       cout<<test; 
       in>>test;
       cout<<test;           
       in>>test;
       cout<<test;           
       in>>test;
       cout<<test;           
       in>>test;
       cout<<test;           
       
       cin>>test; //simply so the window stays open
    }
    And input.txt contains:

    Code:
    1
    5
    3
    The output I got was this:

    Code:
    15333
    Also if I wanted to prompt the user for the filename shouldn't I be able to simply do a cin>>someString and then where I have "input.txt" above when defining my ifstream object just put someString in place of "input.txt"? I kept getting errors when doing this.
    Last edited by Loctan; 03-07-2005 at 02:15 AM.

  2. #2
    Registered User
    Join Date
    May 2003
    Posts
    195
    When you open a file from user input name I think its like

    ifstream file(name.c_str());

  3. #3
    Registered User
    Join Date
    Jan 2003
    Posts
    78
    This is what you need to do:
    1)create a buffer to store one line of text from the file
    2)open the file for reading
    3) test the stream to make sure it is open
    4) read one line from the file
    5) test for end of file
    6) if end of file, quit
    7) else increment line count, goto 4

    Hints:
    1) use: char line[256]; for the buffer
    2) use: int count=0; to hold the line count
    3) use: if(in) to test the stream for open state
    4) use: while( in.getline(line, 256, '\n')) to read from the file and test for end of file in one line of code;
    5) use: ++count; to increment the count

    I gave you a lot of big hints because you are very new at C++. See if you can put this "old school" code together.

    edit:
    you can get the users input like this
    Code:
    char filename[MAX_PATH];  // need a place to put the filename
    
    std::cout << "filename: ";
    std::cin >> filename;
    
    // use filename to open the stream
    Rog
    Last edited by Rog; 03-07-2005 at 04:27 AM.

  4. #4
    Registered User Micko's Avatar
    Join Date
    Nov 2003
    Posts
    715
    Quote Originally Posted by Rog
    4) use: while( in.getline(line, 256, '\n')) to read from the file and test for end of file in one line of code;
    I totally agree, when you encounter EOF or other error, test condition in while loop will become false and loop exits.
    However you can check especially for EOf with something like this:
    Code:
    if (ifstream::eofbit)
    	cout<<"EOF";
    of course after exiting the loop.
    I'm not sure if this is correct way to know for sure if loop exit because of EOF. Can you agree with this?

  5. #5
    Registered User
    Join Date
    Jan 2003
    Posts
    78
    Quote Originally Posted by Micko
    I totally agree, when you encounter EOF or other error, test condition in while loop will become false and loop exits.
    However you can check especially for EOf with something like this:
    Code:
    if (ifstream::eofbit)
    	cout<<"EOF";
    of course after exiting the loop.
    I'm not sure if this is correct way to know for sure if loop exit because of EOF. Can you agree with this?
    Sure, you could use state flags to test for eof. I believe it is ios_base::eofbit. You can read the flags directly and do bitwise comparisons, though I prefer to use the built in functions...

    good()
    eof()
    fail()
    bad()

    ...so, in the code above I would add:

    Code:
    if (in.eof()) cout << ""EOF";
    else I would need something like this:

    Code:
    ifstream::iostate s = in.rdstate();
    if (s & ifstream::eofbit)
    	cout << "EOF\n\n";
    I like the first because it is much more concise.

    Have a nice day!
    -Rog

  6. #6
    Registered User
    Join Date
    Apr 2003
    Posts
    2,663
    I gave you a lot of big hints because you are very new at C++.
    Beginners tend get nervous and/or confused when they encounter stuff like:

    std::cout
    std::cin

    and something like this is a death knell:

    ios_base::eofbit
    Last edited by 7stud; 03-07-2005 at 06:40 AM.

  7. #7
    Registered User
    Join Date
    Jan 2003
    Posts
    78
    Hmmm... good point. though the ios_base was in response to a different question from a different poster.

    edit #1: fixed misspelled word

  8. #8
    email for MystWind avatar MystWind's Avatar
    Join Date
    Feb 2005
    Location
    Holland , The Hague
    Posts
    88

    Thumbs down

    7) else increment line count, goto 4
    ARRGHH ! DON'T use goto !not one self respecting programmer uses the goto comand... evry thing you do with goto can be do with loops .
    PLay MystWind beta , within two years

  9. #9
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    DON'T use goto !not one self respecting programmer uses the goto comand... evry thing you do with goto can be do with loops .
    Um, Rog was stating a series of instructions in English, not writing a program.
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  10. #10
    System.out.println("");
    Join Date
    Jan 2005
    Posts
    84
    Quote Originally Posted by KneeGrow
    When you open a file from user input name I think its like

    ifstream file(name.c_str());

    I am still a little confused. Suppose I wanted the object name to be "in" and the name for the file was stored as a string named "fileName"

    Wouldn't it be:

    ifstream in(fileName.c_str())

    I can't seem to get it to work.

    Thanks for the help guys.
    Last edited by Loctan; 03-07-2005 at 03:55 PM.

  11. #11
    Sweet
    Join Date
    Aug 2002
    Location
    Tucson, Arizona
    Posts
    1,820
    That should be correct can you maybe post some code that we can take a looksie?
    Woop?

  12. #12
    System.out.println("");
    Join Date
    Jan 2005
    Posts
    84
    I figured it out. I didn't have the fileName.c_str() there like I should have.

    Oh, and one more question. I simply use cin is it necessary to use std::cin like I have seen others doing? Thanks in advance.
    Last edited by Loctan; 03-07-2005 at 04:04 PM.

  13. #13
    Sweet
    Join Date
    Aug 2002
    Location
    Tucson, Arizona
    Posts
    1,820
    std::cin is just saying you are using the cin that is in the std namespace. All of the standard functions are in the std namespace.
    I personally use std:: for the things that I use but I am no means the standard.
    Woop?

  14. #14
    Registered User
    Join Date
    Sep 2004
    Posts
    197
    If you use the new headers (as recomended) all of the stuff you get from them will be in the std namespace, and unless you specify that, or import them into the global namespace (using namespace std;) then you have to use the std::, if you import them, then you don't need to. The entire point though of namespaces, is to prevent naming collisions.
    If any part of my post is incorrect, please correct me.

    This post is not guarantied to be correct, and is not to be taken as a matter of fact, but of opinion or a guess, unless otherwise noted.

Popular pages Recent additions subscribe to a feed