Search code examples
cfilesortingbinaryfiles

Merge two binary files in a new file


I have a question about this algorithm that merges 2 sorted input binary files in 1, new binary file. The struct is just an integer:

typedef struct intero_s
{
    int dato;
} intero_t;

Reading, writing and sorting the 2 input files isn't a problem, instead sometimes merging the files doesn't work.

void fusioneNaturale(const char *input1, const char *input2, const char *output)
{
    FILE *finput1 = fopen(input1, "rb");
    if(finput1 == NULL) {
        printf("Impossibile aprire il file!\n");
        exit(1);
    }
    FILE *finput2 = fopen(input2, "rb");
    if(finput2 == NULL) {
        printf("Impossibile aprire il file!\n");
        exit(1);
    }
    FILE *foutput = fopen(output, "wb");
    intero_t recordTemp1, recordTemp2;
    bool prosegui = true;
    while(prosegui) {
        fread(&recordTemp1, sizeof(recordTemp1), 1, finput1);
        fread(&recordTemp2, sizeof(recordTemp2), 1, finput2);
        if(recordTemp1.dato < recordTemp2.dato) {
            fwrite(&recordTemp1, sizeof(recordTemp1), 1, foutput);
            fseek(finput2, sizeof(recordTemp2) * (-1), SEEK_CUR);
        }
        else {
            fwrite(&recordTemp2, sizeof(recordTemp2), 1, foutput);
            fseek(finput1, sizeof(recordTemp1) * (-1), SEEK_CUR);
        }
        if(feof(finput1)) {
            fseek(finput2, sizeof(recordTemp2), SEEK_CUR);
            while(fread(&recordTemp2, sizeof(recordTemp2), 1, finput2)) {
                fwrite(&recordTemp2, sizeof(recordTemp2), 1, foutput);
            }
            prosegui = false;
        }
        if(feof(finput2)) {
            fseek(finput1, sizeof(recordTemp1), SEEK_CUR);
            while(fread(&recordTemp1, sizeof(recordTemp1), 1, finput1)) {
                fwrite(&recordTemp1, sizeof(recordTemp1), 1, foutput);
            }
            prosegui = false;
        }
    }
    fclose(finput1);
    fclose(finput2);
    fclose(foutput);
}

The parameters are the first file's name, the second file's one and the third file's one. For example, if the 2 input files contains respectively {1; 3; 4; 7; 9} and {2; 4; 5; 6; 9; 9} the output file is the correct one, instead if the 2 input files contains respectively {3; 6} and {0; 2; 4; 6; 7; 9} the output file isn't correct.


Solution

  • You unconditionally read a new recordTemp1 and recordTemp1 at every iteration, but note that if one is less than the other, and you wrote that, the next one you read from that input can also be less than the other. So after writing one, you must read another one from that input, i.e., you have "consumed" that one but not yet the other one.

    You must check the return value of fread to detect if you are at the end of the file. If you are at the end of one file, you still must read & write the reamining input from the other file.