Search code examples
carraysstringstrcmpqsort

qsort and strcmp problems when dealing with empty strings and whitespace


I am having a problem getting qsort to work for an array of strings (char * to be exact). I create a compare function that I thought should work for the qsort requirement, but it does not seem to work at all. I also need it to work with whitespace characters and blank strings (ex. ""). Any direction or note on what I am doing wrong would be greatly appreciated.

My relevant source code:

 int compareAlphabetically(const void * a,const  void * b);

void sortStringArray(char * * arrString, int len){
  int size = sizeof(arrString) / sizeof(char *);
  if(*arrString != NULL && len > 1)
    qsort(arrString, size, sizeof(char *), compareAlphabetically);

}

int compareAlphabetically(const void * a, const void * b)
{
  const char *a_p = *(const char **) a;
  const char *b_p = *(const char **) b;
  return strcmp(a_p,b_p);
}

The function definition is (and it should remain unchanged):

/**
 * Takes an array of C-strings, and sorts them alphabetically, ascending.
 *
 * arrString: an array of strings
 * len: length of the array 'arrString'
 *
 * For example, 
 * int len;
 * char * * strArr = explode("lady beatle brew", " ", &len);
 * sortStringArray(strArr, len);
 * char * str = implode(strArr, len, " ");
 * printf("%s\n", str); // beatle brew lady
 *
 * Hint: use the <stdlib.h> function "qsort"
 * Hint: you must _clearly_ understand the typecasts.
 */
void sortStringArray(char * * arrString, int len);

Solution

  • Wrong size calculation.

    size = sizeof(arrString) / sizeof(char *); is likely always 1:
    the size of a pointer (char **) divided by the size of a pointer (char *).

    Code likely needs to use len:

    void sortStringArray(char * * arrString, int len){
      if(*arrString != NULL && len > 1) {
        // qsort(arrString, size, sizeof(char *), compareAlphabetically);
        qsort(arrString, len, sizeof(char *), compareAlphabetically);
      }
    }
    

    [Edit]

    Note: The len > 1 is not functionally needed.
    For a value of 0, len > 1 is not needed. But as len may be less than 0 and size_t is some unsigned type (and changing a negative int to some unsigned tpye is disater), using len > 1 is prudent.