Read it forward, store it in a reversible container, and then walk through the container backward. Or if you know the exact length of each line, you could open the file as binary and use fseek with read to get the lines in reverse. Or you could physically reverse the file before reading it. Or you could use recursion, but that's an exceptionally poor solution. ;)
Narue
Bad Cop
15,460 posts since Sep 2004
Reputation Points: 6,464
Solved Threads: 1,401
>what container would you suggest?
A linked list since you might not know how many lines are in the file.
>is it possible to use some kind of strtok but backwards?
No, the trick here is that you have to get the lines from the file into memory before you can do anything with them. So your problem boils down to either reading the entire file into memory, or using tricky seeking to actually read the file from end to beginning.
Narue
Bad Cop
15,460 posts since Sep 2004
Reputation Points: 6,464
Solved Threads: 1,401
If the text file is large (and constant), and you need to do this a lot, then reading the whole file once to produce an index is worthwhile.
The index being all the 'tell' positions for the start of each line, so at some future time, you can just 'seek' to the start of any given line and read it.
Salem
Posting Sage
11,531 posts since Dec 2005
Reputation Points: 5,862
Solved Threads: 953
>reading it line by line forward costs too much...
And reading it line by line backward doesn't? :icon_rolleyes: Regardless of your solution, you've got the penalty of reading the file. Unless it's a random access file (unlikely), that involves sequential front-to-back access. Oh, and have you tried any of the suggestions and proven that they all cost too much? I'm willing to bet that you haven't.
Narue
Bad Cop
15,460 posts since Sep 2004
Reputation Points: 6,464
Solved Threads: 1,401
> that is what I wanted to read first and not from the head
Seems to me like you want the 'tail' program.
Or in any event, read forwards from the point you last read to get any new data in the file.
In which case, the answer still stands. You record the 'tell' position of where you got to, then 'seek' to it sometime later, and carry on reading.
Salem
Posting Sage
11,531 posts since Dec 2005
Reputation Points: 5,862
Solved Threads: 953
1. Open the file for read, call fseek() to seek to the end of the file, then call ftell() to get the length of the file. Alternatively you can get the file length by calling stat() or fstat().
2. Allocate a buffer pointer to the file size obtained in #1, above.
3. Read the entire file into that buffer -- you can probably use fread() to read the file all in one shot (assuming the file is small enough).
4. Use another char pointer to transverse the file from end to beginning of the buffer. Something like this example
char *ptr = 0;
char *iobuf = malloc( fileSize );
fread(iobuf,fileSize,fp);
for(ptr = iobuf; ptr >= iobuf; ptr--)
{
// do something with the character at *ptr
}
free(iobuf);
Note the above code snipped does not contain any error checking, which you should add in your program.
Ancient Dragon
Retired & Loving It
30,049 posts since Aug 2005
Reputation Points: 5,662
Solved Threads: 2,343
line 44 should have read < filesize because it is reading filesize bytes.
>>But can you tell me if in the for loop I should be reading each char in ptr into a new target array that should then be passed to an fwrite function for streaming to the target file
No you don't have to create another array. In the for loop I posted just use fputc() to write out each character one at a time. The operating system will buffer them up and optimize the write to disk.
Ancient Dragon
Retired & Loving It
30,049 posts since Aug 2005
Reputation Points: 5,662
Solved Threads: 2,343
You are using the fread function incorrectly by swapping the position of the second and third parameter. The second parameter is not the size of the entire file, but the size of each chunk.
Try changing to fread(iobuf, nblocks, filesize, in) and it should work out to be fine.
~s.o.s~
Failure as a human
11,938 posts since Jun 2006
Reputation Points: 3,281
Solved Threads: 734
You are using the fread function incorrectly by swapping the position of the second and third parameter. The second parameter is not the size of the entire file, but the size of each chunk.
Try changing to fread(iobuf, nblocks, filesize, in) and it should work out to be fine.
I don't think it makes any difference -- I usually do it the way the OP posted and have never had a problem. But, as Narue will probably say, in general it may not be safe to do that.
echobase: post your current program and attach a copy of the file you are working with.
Ancient Dragon
Retired & Loving It
30,049 posts since Aug 2005
Reputation Points: 5,662
Solved Threads: 2,343