0

I hope someone can help me. I'm trying to read file that consists of some amount of structs from below:

struct query {
    int key;
    char surname[16];
    char name[16];
    char patronymic[16];
    char subject[16];
    int grade;
}s;

I need to use mmap() to read some data from file, for example to print all structs with same subject and grade, or print a query that has specific key.

In any other case I would use fopen() and fread() to read file with my structs. Something like this:

FILE *inputFile;
inputFile = fopen("database.dat", "rb");
    while(fread(&s, sizeof(s), 1, inputFile) == 1) {
        printf("\nKey: %d", s.key);
        printf("\nName: %s", s.name);
        printf("\nSurname: %s", s.surname);
        printf("\nPatronymic: %s", s.patronymic);
        printf("\nSubject: %s", s.subject);
        printf("\nGrade: %d", s.grade);
    }

But I can't get my head around mmap() so I have a few questions:

  1. How do I initialize mmap() with my file in first place? I imagine something like this but I'm not sure (let's say that I know how much structs in file, let it be amount and fd is my proprer file descriptor).
mmap(NULL, amount*sizeof(s), PROT_WRITE | PROT_READ, MAP_SHARED, fd, 0); 

Also what type of variable I assign this to so I can work with it?

  1. How do I go through all the structs in mapped file and compare their fields? Normally (with fread()) I would just do nested cycles. But I have no idea what to do in mapped case.
  2. Is it possible to mmap() file without knowing amount of structs? In first question I assumed that I know file length (amount*sizeof(s)). Can I map file without knowing amount?

I'm sorry if my terminology sounds off, I'm not really good at English.

klutt
  • 30,332
  • 17
  • 55
  • 95
  • 2
    *"I imagine something like this"* - Then the next step is to try it out and see what happens. Also, please don't tag spam. C or C++? – klutt Oct 18 '20 at 11:21
  • Your file is an array of structs, so what type do you think it should be? – stark Oct 18 '20 at 11:32
  • `mmap` has a reference page that documents what all of its parameters are and explains how to use them. Did you read `mmap`'s documentation? If so, which part of `mmap`'s documentation, specifically, are you unclear about? If not, you should read it first, and ask questions if something in the documentation is unclear to you. – Sam Varshavchik Oct 18 '20 at 12:00
  • 1) I'm using C syntax, but I'm compiling with `g++` so C++ code is also acceptable. 2) Thanks for clarification, I didn't know about being array of stucts. – realkarmakun Oct 18 '20 at 12:22
  • When you're using a C++ compiler, tag it C++. There are some things that you need to do different in C and C++, for instance casting. I removed the C tag. – klutt Oct 18 '20 at 16:04
  • Both tags would be a good idea if you had a hard requirement that it needs to compile in both languages, but I suspect that's not the case ;) – klutt Oct 18 '20 at 16:19

1 Answers1

0

mmap() can treat a file as being on memory. And you don't need to know the file size. See the sample code below:

    fd = open(filename, O_RDWR);
    fstat(fd, &buf);
    t = (struct query *)mmap(NULL, buf.st_size, PROT_WRITE | PROT_READ, MAP_SHARED, fd, 0);
    for(i = 0; i < buf.st_size/sizeof(struct query); i++){
        printf("\nKey: %d", t[i].key);
        printf("\nName: %s", t[i].name);
        printf("\nSurname: %s", t[i].surname);
        printf("\nPatronymic: %s", t[i].patronymic);
        printf("\nSubject: %s", t[i].subject);
        printf("\nGrade: %d", t[i].grade);
    }
    close(fd);
etsuhisa
  • 1,698
  • 1
  • 5
  • 7