JuMoGar
JuMoGar

Reputation: 1760

C - create a bin file of a structs's array inside other struct's array with fwrite

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?

Upvotes: 1

Views: 68

Answers (2)

Adam VZ
Adam VZ

Reputation: 490

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;
}

Upvotes: 1

dbush
dbush

Reputation: 224927

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);
}

Upvotes: 3

Related Questions