Getting the last line in a .txt file

Can't seem to find an easy way to do it, any suggestions/pointers as to what I need to do it?
Two ways:
1) read all lines in the file, keep remembering the last one.
2) Seek to the end of the file and read one character (or a small block) at a time from the end until you find a newline.

1) is obviously inefficient for large files but is very simple, 2) would be the correct way to do it.
So for 2), something like this?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
int i = 0;
char b;
char * c;

LF.seekg( i, std::ios::end );
LF.read( &b, 1 );

while( b != '\n' )
{
    i++;
    LF.seekg( i, std::ios::end );
    LF.read( &b, 1 );
}

if( i != 0 )
{
    c = new char[ i ];
    LF.read( c, i );
}


(LF is the fstream)
Last edited on
No, not really, you need to go backward, not forward. And you only go to the end of the file once.

It'd recommend this:
http://www.cplusplus.com/reference/iostream/istream/unget/
You would unget() from the end of the file, read in a character, then unget twice more, then get another character, etc.
How About this
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#include <cstdlib>
#include <iostream>
#include <fstream>

using namespace std;

int main(int argc, char *argv[])
{
    char temp[50];
    ifstream file;
    
    file.open("D:\\ab.txt");
    while(!file.eof())
    {
     file.getline(temp,256);                  
    }
    cout<<"The last line is "<<temp<<endl;
    system("PAUSE");
    return EXIT_SUCCESS;
}
What if a line is more than 50 characters long? You can't put 256 characters into a size 50 character array. Also, that uses the first method, the OP has decided on the second method.
Last edited on
he can modify my code
and I think.. its simple, right?
Modify your code? If you mean comment it out and write the correct code under it then sure. The point is, that code uses the first method, and the OP wants to use the second method; they're completely different.
Last edited on
@L B
The ungetc() method doesn't work like that. (I suppose it could, but the standard does not require it, and no library I know of does it.)

@qabil
Don't loop on eof().

@asdfg
Of the two methods given you, the first is by far the easiest with the fewest caveats. The only thing you would want to consider is any trailing empty lines in the file. (Most text files have an empty line as the last line in the file. The C and C++ standards even recommend it for source files.)

The second option requires some careful programming and bookkeeping to make it work right. Unless you know that you will be using this on super ultra huge files, go with the first option -- it is fast enough.

(I am currently moving and so have limited time for posting stuff, so I don't know if I can get you an example of doing the second option properly any time soon.)
if I were you, I'd sneak a peek at coreutils' tail code

http://ftp.gnu.org/gnu/coreutils/
I would also go with the first solution, but as an alternative you could use mmap and used std::find with the reverse_iterator adapter to look for the first '\n' starting from the end of the file.
Topic archived. No new replies allowed.