Question

I have a file containing the data(of signed numbers) arranged as follows:

   291
 -1332
   912
   915
 -1347
   196
  1110
  -997
   120
  1017
  -775
  -443
   985
    13
  -690
   369
   673
  -826
   -14
   891
  -546...(thousands of lines)

I want to use a function which will move my file pointer to particular number of line for ex.1100

currently I am using following code to skip and go to particular line/number

if (offset>0)//offset is number of destination line
{
 while(fscanf(f,"%d",&buffer)!=EOF) //f is file pointer ;Buffer is int variable
   { 
    i++;
    if(i==offset)
            break;
    }

}

I want to use better code than this as this code takes more time as offset increases, Any ideas to implement this in easy way ( and for shorter time)?

Était-ce utile?

La solution

If all your numbers are (for example) six characters in length, and you have a single \n newline character at the end of each line, you can get to line number n (zero-based) by fseeking to n * 7. Line 0 is at offset 0, line 1 at offset 7, line 2 at offset 14 and so on.

Similarly, line 1100 (the 1101st line), could be gotten to with something like:

if (fseek (f, 7700L, SEEK_SET) != 0) {
    // something went wrong.
}
if (fscanf (f, "%d", &buffer) != 1) {
    // something else went wrong.
}

That will work for any fixed width line, you just have to adjust the multiplication factor based on the line width and the line endings (for example, DOS encoding may have two characters, \r\n).

Of course, you may find it advantageous to just read the entire file into an integer array in memory (depending on how many thousands there are) so that random access to the data becomes blindingly fast - that's because there's no reason to go back to the file for any data after the initial load.

Autres conseils

You have some options. If you have to keep a text file of numbers, and since each line is a variable length, you could:

  • mmap (memory map) the contents of the file and index the line numbers to an array. For this you would need to make a single pass of the file and generate an array of file offsets where each line begins.
  • Re-write the file as binary data (array of ints, for example) - it is more compact and faster to seek since each integer is found at nth_int * sizeof(int). You pay the penalty once at the beginning to re-write the file.
  • Much depends on your environment and use cases and that's where your better judgement rules. Above all, test and measure to see if its worth it.
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top