Suraj
Suraj

Reputation: 91

Is it possible to read any particular data directly from a file?

Is it possible to read any particular data directly from a file without reading line by line or character by character or block by block ?

I have stored name, roll, marks and passing year of few students in file. Below is the contents of file..

suraj
1
411
2020
john
3
400
2005
aman raj
5
389
2015

I want to print only passing year of a student name john. Below is my code..

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int main()
{
    char name[20];
    int roll;
    int total_marks;
    int passing_year;

    FILE *ptr;
    ptr = fopen("/storage/testing.txt", "r");
    if (ptr == NULL)
    {
        perror("File not found");
        exit(-1);
    }

    while (feof(ptr) == 0)
    {
        fgets(name, 20, ptr); // *Edit: The 2nd argument will less or equal to 20. 
        fscanf(ptr, "%d\n", &roll);//line 1
        fscanf(ptr, "%d\n", &total_marks);//line 2
        fscanf(ptr, "%d\n", &passing_year);//line 3

        if (strcmp(name, "john\n") == 0) //\n because fgets() add newline before \0 (only if size specified is more than no. of characters)
            printf("passing year of John was %d\n", passing_year);
    }
    return 0;
}

Program runs successfully. Below is the result from console..

passing year of John was 2005

[Program finished]

Here, I require only passing year of john but I have to read the whole file. Of course, I can change pointing position by fseek() but then also I have to read minimum line 1, line 2 and line 3. I want to know that, is there any way by which we can read the particular data directly from the file as we used in case of variables in console I/O (temporary storage)? why can't we access data from file similarly as console(using variables) ?

Upvotes: 1

Views: 127

Answers (2)

Steve Summit
Steve Summit

Reputation: 47923

[partial, incomplete answer]

It can be useful to use a separate index — perhaps in a separate file — to enable efficient lookup and seeking into your main database. For example, consider this file:

aman raj   33
john       17
suraj      0

It's in alphabetical order by name, so you can theoretically use binary search in it. The second column gives you a number you can hand to fseek to jump directly to the desired record in the main data file you initially presented in your question (using fseek calls as described elsewhere).

(Although you can't see it, I'm imagining that the two columns in this file are separated by a single tab character, so that there won't be any ambiguity involving spaces in names like aman raj.)

Alternatively, here is an index into the data file in @pmg's answer. In this index, the number in the second column is a record number, not a raw fseek offset. (That is, the number in the second column is the number which must be multiplied by 27 to get the fseek offset in pmg's code.)

aman raj   2
john       1
pmg        3
suraj      0

Another likely possibility, which is more involved to illustrate so I'm not going to do that here yet, is a hash table.

Upvotes: 1

pmg
pmg

Reputation: 108968

If each student occupies the same space in file (and the file is, possibly, no longer a text file) you can fseek() to any specific index

suraj    |  1 | 411 | 2020\n           // 27 bytes per student
john     |  3 | 400 | 2005\n           // still a text file
aman raj |  5 | 389 | 2015\n           // uses more space than a
pmg      | 42 |  87 | 2000\n           // more efficient format

fseek(studentfile, 27 * 2, SEEK_SET);
fgets(buffer, 28, studentfile); // read aman raj data

Upvotes: 2

Related Questions