Click here to Skip to main content
15,891,704 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
Hi All

If you use the following to find the size of a file and then effectively read every character of the file until the end of the file:

long begin, end, size;
ifstream myfile ("example.txt");
begin = myfile.tellg();
myfile.seekg (0, ios::end);
end = myfile.tellg();
myfile.seekg (0, ios::beg);
size = end - begin;

do
{
  myfile.get();
  size--;
}while( !myfile.eof() );


After running this I was expecting size to equal 0 however it was approx 114000. Is this down to whitespace in the text file or something else??? I know it is getting to the end of the file as I temporarily put some extra code in to catch the last 20 characters and it matched the end of the file.

Any help appreciated.

Thanks
Andy

Update - Have now run this exact code as a seperate project as a console app and am having the same problem so it is not other code causing the problem.
Posted
Updated 5-May-10 2:21am
v2
Comments
Richard MacCutchan 5-May-10 9:18am    
Re your comment below: Yes, the original was ordinary text (contains CR/LF), and I think the reader senses EOF one character early. A binary file works as noted below and leaves the size variable set to -1. I don't know what's happening with your test, but you may want to use the debugger to get more information.
Richard MacCutchan 5-May-10 10:38am    
Update: Using ios::binary gives -1 as the result, using text mode gives 1 if the file ends with CR/LF on a blank line.

The reason is this: when you get characters from the text file using myfile.get(), the ifstream object read a new character from the file in translated mode, i.e. it replace CR-LF sequences from the file to a single CR character.
Another issue is that the ifstream::eof() method returns true not when there are no more characters to read, but only after that you have read a new character past the end of the file.
You can fix your problem this way:

C++
long begin, end, size;
ifstream myfile("example.txt");
begin = myfile.tellg();
myfile.seekg(0, ios::end);
end = myfile.tellg();
myfile.seekg(0, ios::beg);
size = end - begin;

ifstream::int_type character;
while ((character = myfile.get()) != EOF)
{
   if (character == '\n') size -= 2;
   else size -= 1;
}
 
Share this answer
 
Comments
Andy Melville 7-May-10 4:34am    
Thanks for this - makes sense to me now.
I just tried this and got to the end with size being equal to 1 at the end, which seems correct. Perhaps you have some other code that is corrupting your size variable. I did also notice the line
C++
size = end - beg;

which does not compile on my system, I think the second variable should be begin.

[edit]My previous test was flawed. If I use a non text file then size counts down to -1 because you always decrement its value after the myfile.get() call, even if that was the end of file condition.[/edit]
 
Share this answer
 
v2
Comments
Andy Melville 5-May-10 8:04am    
Yep should have been begin. Interesting it works on your implementation. Did you have carriage returns in your file???

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900