2

I would like to read a file line by line from the end. I looked at a c++ function like fgets but file is being read in reverse.

TheBoyan
  • 6,802
  • 3
  • 45
  • 61
CrazyC
  • 1,840
  • 6
  • 39
  • 60
  • If load entire file to memory is reasonably for you - you can simply read file line by line to some std container and then reverse this container. – triclosan Jul 19 '11 at 12:49

3 Answers3

7

Unless the file is really big, just read the entire file into a std::vector<std::string>, and then use the reverse_iterator you get from std::vector<>::rbegin()

MSalters
  • 173,980
  • 10
  • 155
  • 350
  • 1
    files are in GB and have to search it from end of file. – CrazyC Jul 19 '11 at 13:05
  • @Saurabh01: Ah, that classifies as "really" big. Would have been better to add that. Before I add another answer, what do you need to do with those lines? How are you going to process them? Obviously you're not going to present the entire GB of text interactively to a user. – MSalters Jul 19 '11 at 13:47
  • Then read the last GB (or so) to memory and process that, then read the second but last segment, and so on. – Bo Persson Jul 19 '11 at 14:24
  • That was what I was thinking, too, but you have some (literal) edge cases there. Also you might want a memory-mapped file. – MSalters Jul 19 '11 at 14:36
  • @MSalters, file have one record per line and i am searching a key in line and process will end as key encountered. – CrazyC Jul 20 '11 at 11:57
1

Unfortunately, I am not aware of any built-in function that would read in reverse. One option would be to implement algorithm of one's own as shown below using fseek, fread and ftell

  1. Seek to last character
  2. Start searching for NEWLINE character from current character
  3. If not newline, add character to string
  4. If newline, reverse the string to get the line
  5. Seek to previous character
  6. Repeat steps 2, 3, 4, 5 till you reach start of file.

You can use ftell, fseek functions to reach last character and then to previous character.

Lightness Races in Orbit
  • 378,754
  • 76
  • 643
  • 1,055
Oak Bytes
  • 4,649
  • 4
  • 36
  • 53
0

If the file size is small use MSalters answer.

If the file size is large, you will have to do the filepointer book keeping manually using iostream::seekg functions. The algorithm would be something like:

  1. find the file size
  2. seek to the offset desired
  3. read
  4. seek to the next offset
nathan
  • 5,513
  • 4
  • 35
  • 47
  • `seekg` for get in this case. – user786653 Jul 19 '11 at 12:57
  • 1
    And the read is of course forward, not backwards (but initially from some point near the end). @Saurabh01: Disk drives are one-way streets; the driver itself can only read in one direction. You have to emulate reading in reverse in software. – David Hammen Jul 19 '11 at 13:30