0

I'm trying to compare two .txt files line-by-line. From the two files, I want to print a third .txt file with all the strings of the first two files, without any repeats and in alphabetical order. When I try running the code I get a segmentation fault for the qsort.

The way I went about this was storing each file in an array of strings, then comparing the arrays. I decided to store the currents array into the outputs array to start, then compare the inputs array and store any strings that are unique to the inputs array. When I try to alphabetize my outputs array, I get a seg fault. All memory is freed correctly. All files can open.

static int Comp(const void* a, const void* b)
{
        return strcmp(*(const char**)a, *(const char**)b);
}

void comparison(char** inputs, int in_file_len, char** currents, int 
curr_file_len, FILE* output_file)
{
        int out_file_len = in_file_len + curr_file_len;
        char** outputs = malloc(sizeof(*outputs) * out_file_len);
        for(int i = 0; i < out_file_len; i++)//allocate memory for outputs
        {
                outputs[i] = malloc(sizeof(**outputs) * 100);
                outputs[i] = "zzzz\n";
        }
        for(int m = 0; m < curr_file_len; m++)//store the current file
        {
                strcpy(outputs[m], currents[m]);
        }
        int x = curr_file_len; //outputs place holder
        for(int j = 0; j < in_file_len; j++)
        {
                for(int k = 0; k < curr_file_len; k++)
                {
                        if(strcmp(inputs[j], currents[k]) == 0)
                        {
                                k = curr_file_len;
                        }
                        else if(k == (curr_file_len - 1))
                        {
                                strcpy(outputs[x], inputs[j]);
                                x++;
                        }
                }
        }
        qsort(outputs, out_file_len, sizeof(**outputs) * 100, Comp);
                for(int n = 0; n < out_file_len; n++)
                {
                        if(strcmp(outputs[n], "zzzz\n") == 0)
                        {
                                free(outputs[n]);
                        }
                        else
                        {
                                fprintf(output_file, "%s", outputs[n]);
                                free(outputs[n]);
                        }
                }  
        free(outputs);
}

I expect there to be a new .txt file created from the outputs array that has all the strings from the first two .txt files in alphabetical order without repeats.

M_G
  • 1
  • 2
  • 3
    Take a close look at the statement `outputs[i] = "zzzz\n";` Think about what it does. – Some programmer dude Jul 29 '19 at 19:18
  • can strcpy not copy over to already filled strings? – M_G Jul 29 '19 at 19:20
  • 2
    What you're doing with that assignment is almost like `int a = 5; a = 10;` and then wonder why `a` isn't equal to `5` anymore. You ***reassign*** the pointer, you don't copy to the allocated memory. To copy a string you need to use `strcpy`. – Some programmer dude Jul 29 '19 at 19:21
  • ooooohhhhhhh, so i should use strcpy when making that "zzzz\n" assignment – M_G Jul 29 '19 at 19:24
  • Also, this code doesn't show where currents[] is being filled in. Perhaps those strings are not properly terminated, or are longer than 100 bytes? – Lee Daniel Crocker Jul 29 '19 at 19:30
  • @LeeDanielCrocker I used the same allocation method for outputs, inputs, and currents. Only outputs is filled with "zzzz\n" when initialized. – M_G Jul 29 '19 at 19:32
  • Don't feel too bad. It is hard to use C's qsort without seg-faulting! – Justsalt Jul 29 '19 at 19:40
  • 1
    The third argument for `qsort` is `sizeof(**outputs) * 100` but that is **not** the size of each array element, which is a pointer. The function is sorting an array of pointers. – Weather Vane Jul 29 '19 at 19:41
  • @WeatherVane Isn't that what I set the size of each array element when I initialized it? – M_G Jul 29 '19 at 19:43
  • 1
    That's the size of what is being pointed **to**. The third argument should be `sizeof(outputs[0])` – Weather Vane Jul 29 '19 at 19:44

0 Answers0