Write to file using hash function and cubes

2

I'm doing a function that reads a series of elements from a binary file and I have to pass them to another file that organizes them into cubes using the hash dispersion method. Here's the function:

int creaHash(char *fichEntrada,char *fichHash){

FILE *f;
FILE *fHash;
tipoAlumno alumno;
tipoCubo cubo;
int i = 0, registro, dni;
int numCubos =CUBOS+CUBOSDESBORDE;

creaHvacio(fichHash);

f = fopen(fichEntrada, "rb");
fHash = fopen(fichHash, "r+b");

while(!feof(f)){

    fread(&alumno, sizeof(tipoAlumno), 1, f);
    registro = atoi(alumno.dni) % CUBOS;

    //Buscamos el numero de cubo correspondiente
    fseek(fHash, registro*sizeof(tipoCubo), SEEK_SET);
    fread(&cubo, sizeof(tipoCubo), 1, fHash);

    if(cubo.numRegAsignados <= C){                  //Podemos escribir en el cubo porque no está lleno

        fseek(fHash, registro*sizeof(tipoCubo), SEEK_SET);
        fwrite(&cubo, sizeof(tipoCubo), 1, fHash);
        cubo.numRegAsignados++;
    }
    else{

        //cubo desbordado
    }
}




fclose(f);
fclose(fHash);

tipoAlumno and tipoCubo are two structures. The function would work like this:

  • Leo fichEntrada and for each entry, I get a number making a atoi of the dni.
  • I move to the cube that corresponds to that number by fseek .
  • I read the cube, if it is not overflowed, I insert the element I read as fichEntrada and increase the numeroRefAsignados .
  • But he does not write anything. Something I'm leaving that I can not find. Thanks for the help!

        
    asked by Mario Hernandez 23.05.2018 в 23:45
    source

    1 answer

    2

    It is possible that the process is failing in any of the operations of fopen , fread , fseek or fwrite but since you do not check if the operations work you can not know it.

    • If fopen fails : A null pointer is returned.
    • If fread fails : The position of the read pointer in the file is left in an indeterminate state. The call to the function returns the number of items read, if an error occurred during the reading this amount will be less than what was requested read.
    • If fseek fails : Deviate a value other than 0 and the reading pointer of the file is not modified.
    • If fwrite fails : Since the call to the function returns the number of written elements, if an error occurred during the writing this amount will be less than what was requested to write.

    Knowing this, we could modify your code to inform you of where it is failing:

    int creaHash(char *fichEntrada,char *fichHash){
        FILE *f = fopen(fichEntrada, "rb");
        FILE *fHash = fopen(fichHash, "r+b");
    
        tipoAlumno alumno;
        tipoCubo cubo;
    
        int i = 0, registro, dni;
        int numCubos =CUBOS+CUBOSDESBORDE;
    
        if (f && fHash){
    
            creaHvacio(fichHash);
    
            while(!feof(f)){
    
                if (fread(&alumno, 1, sizeof(tipoAlumno) f) == sizeof(tipoAlumno)){
                    registro = atoi(alumno.dni) % CUBOS;
    
                    //Buscamos el numero de cubo correspondiente
                    if (fseek(fHash, registro*sizeof(tipoCubo), SEEK_SET)){
                        printf("Fallo al mover el puntero de lectura de fHash\n");
                    }
                    else{
                        if (fread(&cubo, 1, sizeof(tipoCubo), fHash) == sizeof(tipoCubo)){
                            if(cubo.numRegAsignados <= C){ //Podemos escribir en el cubo porque no está lleno
                                cubo.numRegAsignados++;
                                if (fwrite(&cubo, 1, sizeof(tipoCubo), fHash) == sizeof(tipoCubo)){
                                    //todo bien
                                }
                                else{
                                    printf("Fallo en la escritura de cubo\n");
                                }
                            }
                            else{
                                //cubo desbordado
                            }
                        }
                        else{
                            printf("Fallo en la lectura de cubo\n");
                        }
                    }
                }
                else{
                    printf("Fallo en la lectura de alumno\n");
                }
            }
        }
        else{
            printf("No se pudieron abrir los archivos!\n");
        }
    }
    

    The code is more cumbersome but you should not miss any errors and can tell you what problem you have. For this to be possible I have made the following changes:

  • Check that f and fHash contain non-null pointers: Otherwise one of them will have failed to open fichEntrada or fichHash .
  • Reverse the arguments size and count in the calls to fread and fwrite : That way instead of reading / writing a tipoAlumno / tipoCubo we read as many bytes as they occupy those structures, if the reading is correct, it will read its full size.
  • Check that fseek has worked.
  • I eliminated the fseek additional within the cube overflow check, the pointer was already in the position you were asking to move.
  • Increase the tally count of the cube before writing it: If not, the count will always be one value behind.
  • answered by 24.05.2018 в 13:28