Need help using qsort with an array of structs

前端 未结 4 2005
忘掉有多难
忘掉有多难 2020-11-29 07:39

Now, I have seen various examples, but I don\'t get what they mean.

Here\'s my structure

typedef struct profile{
    char gender[1];
    double soc;
         


        
相关标签:
4条回答
  • 2020-11-29 08:09

    Your Soc should almost certainly not be of type double, but anyway here's an example of what a compare function needs to return:

    int compare(const void *p1, const void *p2)
    {
        const struct profile *elem1 = p1;    
        const struct profile *elem2 = p2;
    
       if (elem1->soc < elem2->soc)
          return -1;
       else if (elem1->soc > elem2->soc)
          return 1;
       else
          return 0;
    }
    

    Thanks for pointing out the const void *.

    Here is a complete example (archived): Sorting Structures with the C qsort() Function

    0 讨论(0)
  • 2020-11-29 08:10

    The strict version of a comparator takes two constant void pointers:

    int compare(const void *v1, const void *v2)
    {
        const struct profile *p1 = v1;
        const struct profile *p2 = v2;
        if (p1->gender > p2->gender)
            return(+1);
        else if (p1->gender < p2->gender)
            return(-1);
        else if (p1->soc > p2->soc)
            return(+1);
        else if (p1->soc < p2->soc)
            return(-1);
        else
            return(0);
    }
    

    This compares the gender field first, then the soc field. This is how you handle any multipart comparison.

    0 讨论(0)
  • 2020-11-29 08:14

    To sort the array, use qsort() and pass a comparison function.

    Here is one that produces the correct result for all possible values of the price member:

    typedef struct profile {
        char gender[1];
        double soc;
        int price;
        ...
    } PROFILE;
    
    int compare_price(const void *a, const void *b) {
        const PROFILE *oa = a;
        const PROFILE *ob = b;
    
        return (oa->price > ob->price) - (oa->price < ob->price);
    }
    
    int compare_soc(const void *a, const void *b) {
        const PROFILE *oa = a;
        const PROFILE *ob = b;
    
        return (oa->soc > ob->soc) - (oa->soc < ob->soc);
    }
    

    Notes:

    • the simple subtraction of values produces incorrect results if the difference does not fit in the int type. For example -2 and INT_MAX cannot be correctly compared with the subtraction method. It would not work for floating point values either.

    • the above method can be used for all comparable types, including double except for NaN.

    If you wish to handle NaN, here is how to group them at the end:

    #include <math.h>
    
    int compare_soc_nan_at_the_end(const void *a, const void *b) {
        const PROFILE *oa = a;
        const PROFILE *ob = b;
    
        if (isnan(oa->soc)) {
            return isnan(ob->soc) ? 0 : 1;
        } else
        if (isnan(ob->soc)) {
            return -1;
        } else {
            return (oa->soc > ob->soc) - (oa->soc < ob->soc);
        }
    }
    
    0 讨论(0)
  • 2020-11-29 08:26

    Here is an example of using qsort for an array of structs in C

    /* qsort example */
    #include <stdio.h>
    #include <stdlib.h>
    
    typedef struct {
        int price;
        int id;
    } order;
    order list[6];
    int i = 0;
    
    int compare (const void * a, const void * b)
    {
    
      order *orderA = (order *)a;
      order *orderB = (order *)b;
    
      return ( orderB->price - orderA->price );
    }
    
    int main ()
    {
        srand ( time(NULL) );
    
        printf("Before sorting\n");
        for(i=0; i<6; i++){ 
            list[i].price = rand()%10;
            list[i].id = i; 
            printf ("Order id = %d Price = %d \n",list[i].id, list[i].price);           
        }
        printf("AFTER sorting\n");
        int n;
        qsort (list, 6, sizeof(order), compare);
        for (n=0; n<6; n++)
             printf ("Order id = %d Price = %d \n",list[n].id, list[n].price);          
        return 0;
    }
    

    hope it helps

    katerina dimitris

    (all regards to pitsi)

    0 讨论(0)
提交回复
热议问题