1

I have a struct's array inside other struct's array and I wanna create a binary file which contains this data (only elements no null).

My structs are:

struct viaje {
    char identificador[30+1];
    char ciudadDestino[30+1];
    char hotel[30+1];
    int numeroNoches;
    char tipoTransporte[30+1];
    float precioAlojamiento;
    float precioDesplazamiento;
};

struct cliente {
    char dni[30+1];
    char nombre[30+1];
    char apellidos[30+1];
    char direccion[30+1];
    struct viaje viajes[50];
    int totalViajes;
} clientes[20];

I am trying next:

// For create bin file
for (i = 0; i < totalClientes; i++) {
    fwrite(clientes[i], sizeof(struct cliente), 1, fp_guardarCargarEstado);
    for (j = 0; j < clientes[i].totalViajes; j++) {
        fwrite(clientes[i].viajes[j], sizeof(struct viaje), 1, fp_guardarCargarEstado);
    }
}


// For read bin file
for (i = 0; i < totalClientes; i++) {
    fread(clientes[i], sizeof(struct cliente), 1, fp_guardarCargarEstado);
    for (j = 0; j < clientes[i].totalViajes; j++) {
        fread(clientes[i].viajes[j], sizeof(struct viaje), 1, fp_guardarCargarEstado);
    }
}

I have not tryed fread yet due to I get two errors in fwrite: error: incompatible type for argument 1 of 'fwrite' and note: expected 'const void *' but argument is of type 'struct cliente'

Why could it be?

2 Answers 2

3

The fread and fwrite functions take a pointer to a memory location as their first parameter. You're instead passing an instance of a struct.

You need to pass in the address of this struct using the address-of operator &. Also, there's no need to write the struct viaje instances separately, since they are already contained within a struct cliente

// For create bin file
for (i = 0; i < totalClientes; i++) {
    fwrite(&clientes[i], sizeof(struct cliente), 1, fp_guardarCargarEstado);
}


// For read bin file
for (i = 0; i < totalClientes; i++) {
    fread(&clientes[i], sizeof(struct cliente), 1, fp_guardarCargarEstado);
}
Sign up to request clarification or add additional context in comments.

3 Comments

Hi! Yes, I have tryed your first code (anidated for) and It creates a extra large file. When I try read it, does not load data. I wanna do a bucle beause I do now want that it saves all data (empty items too), I wanna that only save items which have data
I mean, an array has empty elements and others with content, I want to only store the elements that have content, not all the array elements
Note you can fwrite and fread array of structs on the same machine, but do not consider this a portable solution. It isn't. Different compilers handle padding and alignment in different ways. So if you create a binary file with fwrite containing an array of struct, there is no guarantee you can move that file to another computer, recompile your code, and fread the values back in.
1

It looks like there a a few things going on here. There are some important things to note here.

  1. Location of totalViajes in struct cliente
  2. The number of bytes you want to write in fwrite()
  3. Resetting the FILE* before reading from the file again.

Here is what I used to test what I think you're looking for.

struct viaje {
    char identificador[30+1];
    char ciudadDestino[30+1];
    char hotel[30+1];
    int numeroNoches;
    char tipoTransporte[30+1];
    float precioAlojamiento;
    float precioDesplazamiento;
};
struct cliente {
    int totalViajes;
    char dni[30+1];
    char nombre[30+1];
    char apellidos[30+1];
    char direccion[30+1];
    struct viaje viajes[50];
} clientes[20];

int main()
{
    clientes[0].totalViajes = 1;
    clientes[0].viajes[0].numeroNoches = 52;
    int totalClientes = 1;

    FILE* fp_guardarCargarEstado = fopen("myFile.bin", "wb");
    // For create bin file
    for (int i = 0; i < totalClientes; i++) {
        fwrite(&clientes[i], sizeof(struct cliente)-(sizeof(struct viaje)*50), 1, fp_guardarCargarEstado);
        for (int j = 0; j < clientes[i].totalViajes; j++) {
            fwrite(&clientes[i].viajes[j], sizeof(struct viaje), 1, fp_guardarCargarEstado);
        }
    }
    fclose(fp_guardarCargarEstado);

    // set variables to 0 so you can tell if the read actually does anything
    clientes[0].totalViajes = 0;
    clientes[0].viajes[0].numeroNoches = 0;

    fp_guardarCargarEstado = fopen( "myFile.bin", "rb" );
    // For read bin file
    for (int i = 0; i < totalClientes; i++) {
        fread(&clientes[i], sizeof(struct cliente)-(sizeof(struct viaje)*50), 1, fp_guardarCargarEstado);
        for (int j = 0; j < clientes[i].totalViajes; j++) {
            fread(&clientes[i].viajes[j], sizeof(struct viaje), 1, fp_guardarCargarEstado);
        }
    }

    fclose(fp_guardarCargarEstado);

    printf("%i\n%i", clientes[0].totalViajes, clientes[0].viajes[0].numeroNoches );

    return 0;
}

1 Comment

Thank you so much!! That is what I was looking for. I have tested the code and works fine, it is great.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.