Chris
Chris

Reputation: 49

Double comparing by qsort in C

Can i ask how double sorting Works?

I just want compare two people by number of votes ( for example 10 JAMES and 8 Jack ) should looks like 10 JAMES 8 JACK

i used qsort to make this possible, but if i want sort people with the same number of votes by alpha order (for example 10 JAMES, 8 JACK, 10 ALEXA ) should looks like 10 ALEXA 10 JAMES 8 JACK

my compare functions looks like :

int compare(const void* p1, const void* p2){
           return ( ((const struct student*) p2)->votes - ((const struct student*) p1)->votes );
           int value = (((const struct student*)p2)->name - ((const struct student*)p1)->name);
           if(value==0)
           {
                return stcrmp(((const struct student*) p1)->name - ((const struct student*) p2)->name);
           }

}

and qsort there

qsort ((void*) databaza, size, sizeof(struct student), compare);

But it doesnt work, can anyone explain why? Thanks a lot !

Upvotes: 0

Views: 324

Answers (1)

Vlad from Moscow
Vlad from Moscow

Reputation: 310950

Here you are.

int compare( const void *p1, const void *p2 )
{
    const struct student *left  = p1;
    const struct student *right = p2;

    int result = ( right->votes < left->votes ) - ( left->votes < right->votes );

    return result == 0 ? strcmp( left->name, right->name ) : result;
}

Here is a demonstrative program.

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

#define NAME_SIZE   20
struct student
{
    unsigned int votes;
    char name[NAME_SIZE];
};

int compare( const void *p1, const void *p2 )
{
    const struct student *left  = p1;
    const struct student *right = p2;

    int result = ( right->votes < left->votes ) - ( left->votes < right->votes );

    return result == 0 ? strcmp( left->name, right->name ) : result;
}

int main(void) 
{
    struct student students[] =
    {
        { 10, "JAMES" },
        {  8, "JACK" }, 
        { 10,  "ALEXA" }
    };

    const size_t N = sizeof( students ) / sizeof( *students );

    qsort( students, N, sizeof( struct student ), compare );

    for ( size_t i = 0; i < N; i++ )
    {
        printf( "%2u, %s\n", students[i].votes, students[i].name );
    }
    putchar( '\n' );

    return 0;
}

The program output is

 8, JACK
10, ALEXA
10, JAMES

As for your comparison function

int compare(const void* p1, const void* p2){
           return ( ((const struct student*) p2)->votes - ((const struct student*) p1)->votes );
           int value = (((const struct student*)p2)->name - ((const struct student*)p1)->name);
           if(value==0)
           {
                return stcrmp(((const struct student*) p1)->name - ((const struct student*) p2)->name);
           }

}

then in its beginning there is a return statement. So the code after the return statement will not be executed.

This statement

int value = (((const struct student*)p2)->name - ((const struct student*)p1)->name);

has undefined behavior because there is difference of two pointers that do not point to elements of the same array.

This call

stcrmp(((const struct student*) p1)->name - ((const struct student*) p2)->name);

doea not make sense and will not compile because the function strcmp expects two arguments of the type char *.

Upvotes: 2

Related Questions