you are making this too hard.
you assume the file has 5 lines. it need to work on a 3 line file, or even a file with no end of lines, etc.
position -- only moves 1 byte, but getline affects many. This is not logically compatible.
I had trouble with seek until I changed it to use the streampos type. It did not like integers on my implementation. Dunno if that is something I did wrong or something my compiler did wrong... didn't dig into it, just changed types and kept going.
I mean, say your file is this, and x means end of line, z means EOF
00x
11x
22x
33x
44x
55z
so you find the first x between 4 and 5. then you getline, and that reads 55 (or, not 100% sure, being ON the eoln maybe it reads empty line?) and sets your position back to the end of file. (or the start of 55?) then you subtract 1. then you getline again. Does that logic seem correct (hint, the answer is no).
what I gave you works, though crude. if you want to use end of line, you need to adjust by the length of the strings you found and correct your logic.
here is a real fast crack at doing it via end of line. it didn't work for a file with 2 back to back eolns at the end, and I don't have time to debug it, but its a starting point. You can see it is more trouble.. you have to double getline and check to get the first line if < 5 were found, and more. These extra issues make it harder to get exactly right...
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
|
int main()
{
ifstream ifs("x");
ifs.seekg(0, ios::end);
int len = ifs.tellg();
streampos sp = len;
string s, s2;
int ct = 0;
for(int i = 1; i<=len && ct !=5; i++)
{
sp = len-i;
ifs.seekg(sp);
if(ifs.peek() == 10)
{
ct++;
getline(ifs,s);
getline(ifs,s);
cout << s << endl;
}
}
if(ct != 5)
{
getline(ifs,s);
cout << s << endl;
}
}
|