1

I'm currently trying to perform a merge between two CSV text files(file_a and file_b) into a third file (file_c). All files are sorted by lowest id. However, I've observed that, when checking file_c's content, the last entry from file_a is repeated instead of showing file_b's final entry (which has the highest id). I've been trying to diagnose the problem to no avail.

status_t merge_sort(FILE * file_a,FILE * file_b,FILE*file_c,size_t line_length,registry_t * registry_a,registry_t * registry_b)
{
    char * string_a;
    char * string_b;
    size_t i;
    size_t j;
    char del = '|';
    size_t fields_a;
    size_t fields_b;
    size_t length_a;
    size_t length_b;
    i=0;
    j=0;
    while((string_a=my_getline(file_a,line_length,i))!=NULL&&(string_b=my_getline(file_b,line_length,j))!=NULL)
    {

        registry_a=load_data(split(string_a,del,&length_a,&fields_a),registry_a);
        registry_b=load_data(split(string_b,del,&length_b,&fields_b),registry_b);

        if(registry_a==NULL||registry_b==NULL)
            return ERROR_LOADING_DATA;

        if(registry_a->id > registry_b->id)
        {

            fprintf(file_c, "%s\n",string_b);
            free(string_b);
            j++;

        }

        if (registry_a->id == registry_b->id)
        {
            free(string_a);
            free(string_b);
            return ERROR_INVALID_KEY;

        }
        if (registry_a->id < registry_b->id)
        {
            fprintf(file_c, "%s\n",string_a);
            >puts(string_b);

Here puts(string_b) correct content is outputed

            free(string_b);
            i++;
        }

    }

    free(string_a);
    free(string_b);

    while((my_getline(file_a,line_length,i)!=NULL))
        {

            fprintf(file_c, "%s\n",string_a);
            i++;
            free(string_a);
        }

    while((my_getline(file_b,line_length,j)!=NULL))
        {   
        >   puts(string_b);

Here puts(string_b) outputs file_a's content

            fprintf(file_c, "%s\n",string_b);
            j++;
            free(string_b);
        }

return OK;
}

Heres is my_getline function, which i believe could be causing this.

char * my_getline(FILE * fi,size_t line_length,size_t line_number)
{
size_t i;
char * aux_string;
char * p;
if (fi==NULL)
    return NULL;
if (fseek(fi, 0, SEEK_SET) != 0)
    return NULL;

if ((aux_string = malloc(line_length*sizeof(char)))==NULL)
    return NULL;

i=0;
while(fgets(aux_string,line_length,fi)!=NULL)
{

    if (i==line_number)
    {

        if ((p=strchr(aux_string,'\n'))!=NULL)
        {
            *p='\0';
        }

        return aux_string;  
    }
    i++;

}
return NULL;

}

Finally, I'm only allowed to use ANSI 89/99 functions. Thanks to all who read this long post!

Thomas Dickey
  • 51,086
  • 7
  • 70
  • 105
  • 1
    You're tail while-loops make no sense. `my_getline` returns the line, dynamically allocated. You apparently don't care about that, and just leak that memory, then check the content of a pointer you long-ago already `free`d. Put another way, if this: `while((string_a=my_getline(file_a,line_length,i)) != ...` is in main loop condition (note retained return value), what on earth is this: `while((my_getline(file_b,line_length,j)!=NULL))` supposed to be doing? Right now it's a recipe for a memory leak that just happens to advance the file-get position as well. – WhozCraig May 29 '19 at 00:56

0 Answers0