-2

I am simply trying to read from a text file, parse some information into an "array of strings" and then alphabetize the array using qsort. However, I keep getting a segmentation fault during the sorting part. I am new to C, can anybody take a look at my code and tell me what the problem is?

#include <stdlib.h>
#include <stdio.h>
#include <string.h>

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

int main(int argc, char* argv[]){
    FILE *fp;
    fp = fopen(argv[1], "r"); // argv[1] = "input.txt"
    char allStrings[255][255];
    int stringArrCounter = 0;

    char buff[255]; /* String to put the scanned shit in*/
    char blank[255];
    strcpy(blank, " ");

    int counter = 0;
    while (!feof(fp)){
        char stringer[255];
        char stringer2[255];
        fgets(buff, 255, fp);
        if (strcmp(buff, blank) > 0){
            if (counter % 5 == 0){
                strncpy(stringer, buff, strlen(buff)-1);
            }
            else if (counter % 5 == 1){
                strncat(stringer, buff, strlen(buff)-1);
            }
            else if (counter % 5 == 3){
                strncpy(stringer2, buff, strlen(buff)-10);
                strncat(stringer2, stringer, strlen(stringer));
            }
            else if (counter % 5 == 4){
                strcpy(allStrings[stringArrCounter], stringer2);
                printf("%s\n", stringer2);
                memset(stringer,0,sizeof(stringer));
                memset(stringer2,0,sizeof(stringer2));
                stringArrCounter++;
            }
            counter++;
        }
    }
    qsort(allStrings, 255, sizeof(char *), compare);
}
user3642365
  • 549
  • 1
  • 6
  • 16
  • You code expibits undefined behaviour. Your compiler should warn and you should pay heed to them. Get the types correct, instead of just using `void *` and casting. – too honest for this site Sep 06 '15 at 23:20
  • Can you show us where you're getting the seg fault? Line #? – StephenG Sep 06 '15 at 23:23
  • I'm sorry, this is literally the first thing I've done in C. Olaf, are you talking about the comparator? StephenG, how do I get the line num? – user3642365 Sep 06 '15 at 23:24
  • Rather than `while (!feof(fp)){`, use `while (fgets(buff, sizeof buff, fp) != NULL){` Also remove \n with http://stackoverflow.com/questions/2693776/removing-trailing-newline-character-from-fgets-input/27729970#27729970 – chux - Reinstate Monica Sep 06 '15 at 23:28
  • And... the size of each element in `allStrings` is *not* `sizeof(char*)`. Taking away everything else that is wrong, that along has implosion written all over it. – WhozCraig Sep 06 '15 at 23:29
  • 1
    With `strncpy(stringer, buff, strlen(buff)-1);`, `stringer` is not null character terminated. – chux - Reinstate Monica Sep 06 '15 at 23:31

1 Answers1

0

Here is a short example of how to use qsort with a 2-D array. Note that a 2-D array is different to an array of pointers. It is a contiguous bloc of characters and the compiler will compute offsets in response to the dimensions you give.

#include <stdlib.h>
#include <stdio.h>
#include <string.h>

int comp10(void const *p1, void const *p2)
{
    typedef char const A[10];

    return strcmp( *(A *)p1, *(A *)p2 );
}

int main()
{
    char arr[3][10] = { "pangolin", "fish", "anteater" };

    qsort(arr, sizeof arr / sizeof arr[0], sizeof arr[0], comp10);

    for (int i = 0; i < sizeof arr / sizeof arr[0]; ++i)
        printf("%s\n", arr[i]);
}

Setting up the comparison function and the qsort call correctly is your main issue.

However your code to read the strings from file contains a number of mistakes. Please consult the manual pages for strncpy and strncat and fgets to see what the arguments mean and what output they generate. See here for how to use feof (hint: you should not use it at all).

I would recommend you divide your program into two parts:

  1. The sorting logic, which you will test by using a hardcoded list of strings as in my example
  2. The file reading logic, which you will test by outputting the strings you have read.

Once both tests succeed , then you can feed the output of (2) into the input of (1).

Community
  • 1
  • 1
M.M
  • 138,810
  • 21
  • 208
  • 365