Search code examples
cstructfwrite

C - Create a bin file without NULLs (non-defined) elements is not working


I have an array of struct inside another array of structs and I want to create a binary file which contains the data inside both structs but only elements which are not 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
// 'totalClientes' is a var which contain the number of 'clientes'
for (i = 0; i < totalClientes; i++) {
        fwrite(clientes[i], sizeof(struct cliente), 1, fp_guardarCargarEstado);
        // 'clientes[i].totalViajes' is a var which contain the number of 'viajes' inside actual 'cliente'
        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);
        }
    }

But It creates all elements into the bin file, includes null elements. What is wrong?

Why could it be?

Thank you.


Solution

  • This is because the containing structure cliente contains in your case statically allocated 50 element array of struct viaje. The line fwrite(clientes[i], sizeof(struct cliente), 1, fp_guardarCargarEstado); automatically writes all the elements present within the cliente object i.e , it writes the 50 element array vijae also. Therefore this code is redundant :

     for (j = 0; j < clientes[i].totalViajes; j++) {
                fwrite(clientes[i].viajes[j], sizeof(struct viaje), 1, fp_guardarCargarEstado);
            }
    

    You are writing element that has been already written by the statement : `fwrite(clientes[i], sizeof(struct cliente), 1, fp_guardarCargarEstado); This is the expected behaviour.

    If you don't want this behaviour create a temporary object like:

    struct cliente_temp {
       char dni[30+1];
       char nombre[30+1];
       char apellidos[30+1];
       char direccion[30+1];
       //struct viaje viajes[50]; omit this line or use a pointer struct viaje *viajes;
       int totalViajes;
    } clientes[20];
    

    and copy the original structure to this structure before writing to the file and reading from the file. Then you can use the code for writing the structure vijae :

    for (j = 0; j < clientes[i].totalViajes; j++) {
                fwrite(clientes[i].viajes[j], sizeof(struct viaje), 1, fp_guardarCargarEstado);
            }