Thread: files won't stop being read!!!

  1. #1
    Software Developer jverkoey's Avatar
    Join Date
    Feb 2003
    Location
    New York
    Posts
    1,905

    files won't stop being read!!!

    well, I'm not going to explain the code, because most of you have probably all ready had this problem, but here it is:

    in my program, i read through a file in a while loop and it merely tests this: while(!file.eof()) and then, inside the loop it does this: file.get(buff); now, thing is, if i only have about 6 letters in the file and no endlines, it DOESN'T break out of the loop!!

    i can't seem to understand why it does this, and I'm just getting fed up with it..........so, i'll just search around the cboard till someone replies

    thanks

  2. #2
    Registered User
    Join Date
    Apr 2003
    Posts
    2,663
    What type is the variable buff? Let's see the code.

  3. #3
    Software Developer jverkoey's Avatar
    Join Date
    Feb 2003
    Location
    New York
    Posts
    1,905
    buff is just a char

    Code:
    		ifstream script;
    		script.open(filename,ios::nocreate);
    		char buff2=' ';
    		bool end=false;
    		// testing for if it exists here, not putting it in....
    		while(!script.eof() && !end)			// Test if at the end of the file or END
    		{
    			script.get(buff2);					// Get the current character
    
    			if(buff2==-1)						// Double check if we are at the end of the file
    				break;							// Break out of the loop
    			// .. a bunch more testing here, a few 100 more lines.....:)
    
    		}
    it's pretty basic, i just can't figure out why it's not quitting

  4. #4
    Registered User
    Join Date
    Apr 2003
    Posts
    2,663
    It worked fine for me when I took out:

    ios::nocreate

    with an input file consisting of:

    abcdefgh

  5. #5
    Registered User
    Join Date
    Nov 2002
    Posts
    1,109
    you could try:
    Code:
    while(script.get(buff2))

  6. #6
    i believe you still have to have ios::in or ios::out

    in your case,
    Code:
    script.open(whatever, ios::in | ios::nocreate);
    should do the trick.


    EDIT: no smilies :(
    Compilers:
    GCC on Red Hat 8.1 (Primary)
    GCC on Mac OS X 10.2.4 (Secondary)

    Others:
    MinGW on XP

  7. #7
    Software Developer jverkoey's Avatar
    Join Date
    Feb 2003
    Location
    New York
    Posts
    1,905
    AH HAH!!! I FIGURED IT OUT!! 24 hours later, lmao

    oook, here's the scoop

    what I did was, i figured that i must have been trying to read past the end of the file in to the void where no programmer wants to end up , so I did this:

    Code:
    while(script.peek()!=-1 && !end)
    and that merely looks ahead in the file, testing if it is -1 (end of file), if it is, it quits. I slapped my head when i remember about the peek command

    for anyone who doesn't know, peek looks one byte ahead in the file without actually moving the position of input/output

    thanks for the help everyone

  8. #8
    Registered User
    Join Date
    Apr 2003
    Posts
    2,663
    Slap yourself on the head again because you aren't done yet.

    I'm familiar with peek() and as someone pointed out to me when I used it similarly as you, it's a horrible solution. Why? It requires you to read from the file twice everytime, and file reads are slow to begin with.
    Last edited by 7stud; 04-09-2003 at 12:34 AM.

  9. #9
    Software Developer jverkoey's Avatar
    Join Date
    Feb 2003
    Location
    New York
    Posts
    1,905
    rtsfargfrft *slap*, lol

    oookay, how's about this, i'll just test the exact file size of the file (in bytes), and then just read up to that point? that should theoretically work, just as long as the file doesn't change mid-program (which it doesn't)

  10. #10
    Shadow12345
    Guest
    It has been a while since I've needed to input from a file, but using while(!fin.eof()) or while(fin.good()) really should be working fine, they were made just for this purpose. I'm assuming the file is generated by another executable, so when you're done writing it just make sure it outputs the /0 character, I think that will work (I remember Salem telling me to do that before when I was having the same trouble) EDIT: or maybe it is \0 I don't remember

    Hope that works.

    I'm familiar with peek() and as someone pointed out to me when I used it similarly as you, it's a horrible solution. Why? It requires you to read from the file twice everytime, and file reads are slow to begin with.
    That's why I really like Brett Porter's milkshape3d tutorial, it just gets the size of the file in bytes, then reads that into a byte array, and then the problem is of iterating through the byte array extracting data that is already in memory (so you can peek forward, looking behind, do jumping jacks, whatever and retain speed).
    Last edited by Shadow12345; 04-09-2003 at 07:42 AM.

  11. #11
    Registered User
    Join Date
    Mar 2002
    Posts
    1,595
    eof() doens't look at the input buffer for it's material like other istream methods such as >> or get() or getline() do. It looks at the state variable of objects derived from the ios class, like ifstream objects. Embedded within the state variable is a bit that denotes whether EOF has been encountered or not. If it has then eof() returns non-zero, which means true, and if it hasn't then eof() returns zero, which means false.

    So what? Well, this information is mission critical when reading from files and trying to terminate appropriately when reaching the end of file, as evidenced by finding EOF. Lets say the file contents are:

    abcdefg

    and you are using this code to read the file:
    Code:
    char buff2=' ';
    bool end=false;
    // testing for if it exists here, not putting it in....
    while(!script.eof() && !end)
    // Test if at the end of the file or END
    {
       script.get(buff2);					
      //Get the current character
      if(buff2==-1)					  
      // Double check if we are at the end of the file
      break;
      //do something with buff2 here
    }
    first of all the value of end is never changed in the code once it is
    initialized. It could have been changed after the if(buff2 == -1) statement, but break is used instead, so I would delete any reference to end.

    second, I don't believe -1 is a valid char. It is a valid int, but I don't think it is a valid char. therefore the if(buff2 == -1) statement probably won't work in any event. You could check for some valid char unlikely to be in your file, say a tilde (~) and then the syntax would work. Or you can just drop this completely and use the above knowledge of EOF and eof() to do the job for you.

    note in the above code that no script methods/operators are called before the first call to eof(). Therefore the state variable of script should have the eofbit indicating that EOF has not been found when eof() is called and checks it the first time. Therefore the body of the loop proceeds fine. get() is used to get the first char in the input stream (file). The char isn't EOF so the eofbit in the state variable isn't toggled. And you repeat this 5 times until the f has been read. EOF isn't found at the read of f, so eof() still returns false when it checks the state variable and the next call to get() finds g. g isn't EOF, so the eofbit still isn't toggled, so eof() still will return true even though we have read the last item in the file. OOPS!. Now what happens. Well the file conditional is still true so the loop has to be done one more time, but now you are in no mans land because EOF isn't a storeable char so the program does what it wants (often it will use the last accepted data and repeat it, but don't count on that happening).

    So what to do. Well call an istream method just before the call to eof(). Like this:


    Code:
    char buff2=' ';
    bool end=false;
    
    //first call to script method
    script.get(buff2);
    
    //if file is empty then get EOF found and eofbit is toggled
    //if file isn't empty then EOF isn't found and eofbit isn't toggled
    
    while(!script.eof())
    {					
       //do something with buff2 here
    
       //now try it again
       script.get(buff2);
       
       //if EOF found, eofbit is toggled and eof() will return true so loop will stop without the one extra loop
      //if EOF not found, eofbit won't be toggled and eof() will return false so loop will continue at least one more time
    }

    And there you have it. Slimmed down, buffed up, and ready to go, with a tidy explanation that may dazzle your friends and acquantainces.

    Good luck.

  12. #12
    Registered User
    Join Date
    Apr 2003
    Posts
    2,663
    elad,

    I had that eof problem where the last input is doubled when reading char types, and you explained it perfectly. I too was directed to use this structure:

    Code:
    script.get(buff2);
    
    while(!script.eof())
    {
          //do stuff
    					
          script.get(buff2);
    }

  13. #13
    Software Developer jverkoey's Avatar
    Join Date
    Feb 2003
    Location
    New York
    Posts
    1,905
    errm, just so everyone knows, where it says "do other stuff with buff here", that's where i'm testing EVERYTHING (a few 1000 lines of code) and i assumed you didn't want my whole source code online (i wouldn't put it online anyways, lol)

    but yah, the end thing is just there because i copy/pasted/cut the code right from my code so that i wouldn't have to retype anything

    and about the peek thing....will it REALLY slow the program down that much? i mean, on a grand scale (say you were reading a 10 kb file), would it be a lot slower if i wasn't using the peek? (and please don't say "well, just see for yourself", because i don't really feel like writing a program to do that and timing everything)

    so i just need to know how fast/slow peek is in relation to not using it

  14. #14
    Registered User
    Join Date
    Jan 2003
    Posts
    311
    peek() is probably not particularly slow on a stock fstream. They are buffered by default, it's not like you are doing two consecutive disk reads. My guess is that you are not checking to see if you have actually opened the file. There is a great deal to be said for using a loop of the fourm alpha suggested

    while(script.get(ch))

    eof() implies you have succesfully finished reading the file, not that the file was never opened or some other problem. If you need to test a stream, test .good(), this implies that the next operation might succed. while(script.get(ch)) indirectly tests against good(). After you leave the while loop test eof() to see if something unexpected happened.

  15. #15
    I lurk
    Join Date
    Aug 2002
    Posts
    1,361
    Bleh; I don't know if anyone has mentioned this yet, so here goes:
    Code:
    fin.seekg(0, std::ios::end);
    int size = fin.tellg();
    fin.seekg(0, std::ios::beg);
    
    char* data = new char[size];
    fin.read(data, size);
    Get the filesize, allocate a buffer to the size of filesize and read it in all in one chunk.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. open and read bmp image files
    By cnewbie85 in forum C Programming
    Replies: 2
    Last Post: 05-19-2009, 01:36 AM
  2. Read INDEX.DAT files?
    By Queatrix in forum Windows Programming
    Replies: 3
    Last Post: 09-08-2006, 08:03 AM
  3. how to play play and stop wav files
    By cnu_sree in forum Linux Programming
    Replies: 4
    Last Post: 08-14-2006, 11:11 PM
  4. using threads to write & read from files
    By kishorepalle in forum C Programming
    Replies: 4
    Last Post: 10-19-2004, 05:19 PM
  5. Replies: 3
    Last Post: 05-05-2004, 05:40 PM