kampi
kampi

Reputation: 2484

How to sort a struct using qsort?

I have a struct declared like this

struct data
{
char * Date;
char * String;
};
struct data **RegArray = NULL;

int ArrayCount = 0;

I add new items to the array this way:

struct data **tmp = ( struct data ** )realloc( RegArray, ( ArrayCount + 1 ) * sizeof( struct data * ) );
if ( tmp == NULL )
{
    printf( "\nRealloc failed!" );
    return;
}
RegArray = tmp;

RegArray[ ArrayCount ] = ( struct data * )malloc( sizeof **RegArray );
if ( RegArray[ ArrayCount ] == NULL )
{
    printf( "\nMalloc failed!" );
    return;
}

RegArray[ ArrayCount ]->Date = _strdup( cDate );
RegArray[ ArrayCount ]->String = _strdup( cString );

ArrayCount++;

The function which compares the values:

int CompareByDate( const void *elem1, const void *elem2 )
{
//return ( ( data* )elem1 )->Date > ( ( data* )elem2 )->Date ? 1 : -1;
return strcmp( ( ( data* )elem1 )->Date, ( ( data* )elem2 )->Date );

}//CompareByDate

And finally I call qsort like this:

qsort( RegArray, ArrayCount-1, sizeof( data ), CompareByDate );

The problem is, that the data won't be sorted. So what am I doing wrong?

Thanks!

Upvotes: 1

Views: 309

Answers (1)

Some programmer dude
Some programmer dude

Reputation: 409176

In your qsort call and comparison function, you forget that you're dealing with an "array" of pointers. The easiest change is to not use an array of pointers:

struct data *RegArray = NULL;

/* ... */

struct data *tmp = realloc( RegArray, ( ArrayCount + 1 ) * sizeof( struct data ) );
if ( tmp == NULL )
{
    printf( "\nRealloc failed!" );
    return;
}
RegArray = tmp;

RegArray[ ArrayCount ].Date = _strdup( cDate );
RegArray[ ArrayCount ].String = _strdup( cString );

ArrayCount++;

This will make your qsort call (and comparison function) work as they are shown in the question.


If you don't want to change the code as outlined above, you have to change the qsort call and comparison function:

qsort( RegArray, ArrayCount-1, sizeof( data * ), CompareByDate );

/* ... */

int CompareByDate( const void *elem1, const void *elem2 )
{
    struct data **d1 = (struct data **) elem1;
    struct data **d2 = (struct data **) elem2;

    return strcmp((*d1)->Date, (*d2)->Date);
}

Upvotes: 1

Related Questions