Changing .bin file's data in C

2019-05-14 10:15发布

问题:

I have a lot of data stored in bin format as a sequence of structs. I want to be able to read randomly any of the structs and modify it in C. I am trying with the following code but it doesn't work. Can someone fix it for me please?

Also, would it be possible to delete an intermediate struct from the file in between?

The code is below:

#include <stdio.h>
#include <stdlib.h>

struct rec {
        int x,y,z;
};

void f_rite()
{
        int i;
        FILE *ptr_myfile;
        struct rec my_record;

        ptr_myfile=fopen("test.bin","w");

        for ( i=0; i < 5; i++ ) {
                my_record.x = i;
                fwrite( &my_record, sizeof(struct rec), 1, ptr_myfile );
        }

        fclose(ptr_myfile);

        return;
}


void f_read()
{
        int i;
        FILE *ptr_myfile;
        struct rec my_record;

        ptr_myfile=fopen("test.bin","r");

        for ( i=1; i <= 5; i++) {
                fread(&my_record,sizeof(struct rec),1,ptr_myfile);
                printf("%d\n",my_record.x);
        }
        printf("\n");

        fclose(ptr_myfile);

        return;
}

void f_rerite()
{
        int i;
        FILE *ptr_myfile;
        struct rec my_record;

        ptr_myfile=fopen("test.bin","rw");

        for ( i=5; i >= 0; i-- ) {
                fseek( ptr_myfile, sizeof(struct rec)*i, SEEK_SET );
                fread( &my_record, sizeof(struct rec), 1, ptr_myfile );
                my_record.x = my_record.x + 100;
                fwrite( &my_record, sizeof(struct rec), 1, ptr_myfile );
        }

        fclose(ptr_myfile);

        return;
}

int main()
{
        f_rite();
        f_read();
        f_rerite();
        f_read();

        return 0;
}

回答1:

There is no "rw" flag to fopen. You need "r+" for reading and writing(updating). Since it's binary data, you should actually use "r+b" , and "wb" in your f_rite function and "rb" in your f_read function. Also:

  • Check the return value of calls that could fail, you'd discover that e.g. fwrite failed.
  • Your f_rerite functions iterates through 6 elements, you're off by one.
  • Your f_rerite also writes to the next element. Likely you want to update the current record rather. Which means you need to fseek again after calling fread.


回答2:

"rw" is wrong. Use "r+". Don't forget to seek back after reading.