tags:

views:

72

answers:

3

I'm using this code to read a file into a buffer. The file is full of structs of evaluacion type (including some char and int variables). Now I have the whole file in a buffer, how can I find the values of one variable in the buffer now? For example buf.notamedia < 4. There are supposed to be many of them inside the file.

#include <unistd.h>
#include <sys/stat.h>
int revisanotas(int fd)
{
    int nbytes = 1;
    int nbytese = 0;
    evaluacion buf;
    struct stat datos;
    fstat(fd, &datos);

    printf("Size of file =  %d \n", datos.st_size);
    char *buffer = (char *)malloc(datos.st_size);
    int actual = read(fd, buffer, datos.st_size);

    printf("actual = %d\n", actual);

    if (buf.notamedia >= 4.5 && buf.notamedia < 5)
    {
        /* ... */
    }
}

Any idea is very welcome

+5  A: 

Easiest to define the buffer as a pointer to the data structure and use that to dereference the data (although you should ensure the file size is a multiple of the structure size).

i.e.

evaluacion* buffer = (evaluation*)malloc(datos.st_size);
if(buffer[0].notamedia >= 4.5)

You can then increment the index to access other structures you loaded.

tyranid
Thanks tyranid for the answer. In that case, should I read one struct by one, and read the file every time I search for the variable?What I need to do is to read the file only once, make the operations with the structs in memory and then write the file to the disc again only once.
Peter
If the buffer contains the evaluacions one after the other, then you can just look at buffer[1] for the 2nd one, buffer[2] for the 3rd... Just make sure to divide st_size by sizeof(evaluacion) to make sure you don't go past the end of the file (i.e., don't let your buffer index be greater than st_size/sizeof(evaluacion).
Suppressingfire
A: 

I'm doing as you said, but I'm only getting one iteration, I don't know what I'm doing wrong :(

evaluacion* buffer=(evaluacion*)malloc(datos.st_size);
int actual = read(fd,buffer,datos.st_size);

printf("Number of structs = %d", (datos.st_size/(sizeof(evaluacion))));

for (i=0;i<(datos.st_size/(sizeof(evaluacion)));i++);
{
printf("Notamedia = %f\n",buffer[i].notamedia);
if (buffer[i].notamedia >= 4.5 && buffer[i].notamedia < 5)
{
printf("Notamedia = %f\n",buffer[i].notamedia);
}
{
}
}
}
Peter
If you are only getting one iteration then I guess there is only one structure in the file :) You also technically should check the actual value you read matches what you expected to read as at least on *nix systems _read_ can be interrupted by a signal and so could return less than you asked for.
tyranid
Actually there're 227 structures, at least is the value returned by datos.st_size/(sizeof(evaluacion), so I don't know why the for only returns once :_(
Peter
+1  A: 

Thanks for the comments, I think I solved the problem, I modified the code:

#include <unistd.h>
#include <sys/stat.h>
int revisanotas(int fd)
{
int nbytes=1;
int nbytese=0;
int i=0;
int n=0;
struct stat datos;
fstat(fd, &datos);
evaluacion buf;
printf("File size =  %d \n", datos.st_size);
evaluacion* buffer=(evaluacion*)malloc(datos.st_size);
int actual = read(fd,buffer,datos.st_size);

do 
{
i++;
if (buffer[i].notamedia >= 4.5 && buffer[i].notamedia < 5)
{
n=n+1;
/*printf("Notamedia = %f\n",buffer[i].notamedia);
*/
buffer[i].notamedia=5;
}

}while (i<(datos.st_size/(sizeof(evaluacion)))); 
nbytese=write(fd,buffer,datos.st_size);
printf("Written bytes = %d\n",nbytese);
return(n);
}

Now, If the condition is matched, I'm modifying the buffer. Once I read all the structs I write the file in the disk again, but I still have a problem, every time, instead of write the file in the same position, seems like I'm adding the same information after the old one, so if I read the file once I get 3.5Mb, two times 7MB and so on :S. Any idea what can I do? Thanks

Peter
I think I solved it with lseek, placing the pointer at the beginning before write.lseek(fd,OL,SEEK_SET);:)
Peter