Reading a File Randomly

Random file access isn’t about generating a random value and then reading at that position in the file. While you could do that, the term random access refers to file access that isn’t sequential. I suppose they could have called it dynamic file access, but I was only 8-years-old when computer scientists developed these concepts, so my input would not have been welcome.

Assume that you have a file consisting of formatted data. The data could be written as a series of structures or simply as a collection of similarly-sized variables, such as a series of integers.

For this Lesson, I’m using a file of high scores named high_scores.dat. The file consists of 10 integer values (binary, not text) representing high scores stored largest values first, as in the rank of high scores. Click here to view the code I used to create this file. (WordPress won’t let me upload the raw data because a binary file is considered a security risk.)

To read the entire file, front to back or sequentially, you can use the following code:

#include <stdio.h>

int main()
{
    FILE *fh;
    int x,score;

    fh = fopen("high_scores.dat","r");
    if( fh == NULL)
    {
        perror("Unable to read file\n");
        return(1);
    }
    for(x=0;x<10;x++)
    {
        fread(&score,sizeof(int),1,fh);
        printf("%2d: %d\n",x+1,score);
    }

    fclose(fh);

    return(0);
}

The fread() function at Line 16 fetches an integer value into the variable score. The number of bytes read is set by sizeof(int), and the value 1 directs the fread() function to read only one chunk of data. That value is displayed in Line 17.

Here’s the sample output:

 1: 3333360
 2: 2990950
 3: 2760010
 4: 2525080
 5: 2186670
 6: 1980000
 7: 1976830
 8: 1873420
 9: 1363600
10: 1248910

Those are the high scores, and that’s how binary data is read from a file, which is covered in my C programming books.

Suppose you wanted to know only the sixth highest score, which is 1,980,000. A number of solutions exist to solve that puzzle.

For example, you could read the file’s data into an array and then pluck out the fifth element (which is the sixth highest score). For my solution, I’ll use the fseek() function to specifically locate the 6th record and read only it. Here’s the source code:

#include 

int main()
{
    FILE *fh;
    int score;

    fh = fopen("high_scores.dat","r");
    if( fh == NULL)
    {
        perror("Unable to read file\n");
        return(1);
    }
    fseek(fh,sizeof(int)*5,SEEK_SET);
    fread(&score,sizeof(int),1,fh);
    printf(" 6: %d\n",score);

    fclose(fh);

    return(0);
}

The fseek() function at Line 14 sets the file position indicator to a location the size of five integer values from the start of the file (SEEK_SET). That would be the location of the sixth integer written to the file, which is the value desired. In Line 15, a single integer value is read and stored in the score variable. Line 16 displays that value:

 6: 1980000

You could modify the code further. For example, prompt the user to input which high score value they want to see, then read the file to fetch only that single value. Thanks to the fseek() function and random file access, you don’t need to churn through the entire file just to get that result.

Leave a Reply