Need help using qsort with an array of structures

Now I have seen different examples, but I do not understand what they mean.

Here is my structure

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

where soc is the social security number I'm going to sort.

I know you need a comparison function, but I don’t know how to come up with what I need.

+6
source share
4 answers

Here is an example of using qsort for an array of structures 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 this helps

katerina dimitris

(all relationship to pitsi)

+16
source

Your Soc should almost certainly not be of type double , but in any case, here is an example of what the comparison function should 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 const void *.

Here is a complete example: Sorting structures using the C function qsort ()

+7
source

The strict version of the comparator accepts 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 sex field first, and then the soc field. Here's how you handle any multi-part comparison.

+5
source

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

Here is one that gives 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:

  • simply subtracting the values ​​produces incorrect results if the difference is not int . For example, -2 and INT_MAX cannot be correctly compared with the subtraction method. It will not work for floating point values ​​either.

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

If you want to process NaN , here's 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); } } 
+1
source

Source: https://habr.com/ru/post/888875/


All Articles