Compare structs

May 3, 2014 at 3:47pm
Hello.

How do you compare two structs by 2 arguments.

Lets says I have a struct;

1
2
3
4
struct s {
	char a[5];
	char b[5];
};


I use qsort and first I compare by b. Since b is a number they can be same and if they are I would like to compare those two items by their a also. Can I do that?
May 3, 2014 at 3:56pm
Yes, but you need to write a proper comparison function for qsort() to use. There's more to read here, complete with examples:
http://www.cplusplus.com/faq/sequences/sequencing/sort-stuff/#c

The only thing your compare function need do is properly compare the two structs and return an appropriate integer value (<0, 0, or >0).

Hope this helps.
May 3, 2014 at 4:01pm
Is it normal that qsort is sorting my a's this way:

1
15
2
24

I would like to sort it like:

1
2
15
24

without using int in struct.

The compare function I have is like:

1
2
3
4
5
6
int compare(const void *a, const void *b)
{
    struct s *ia = (struct s *)a;
    struct s *ib = (struct s *)b;
    return strcmp(ia->a, ib->a);
}



EDIT: Nevermind found the atoi function.
Last edited on May 3, 2014 at 4:16pm
May 3, 2014 at 4:21pm
Yes, because the string "15" is less than the string "2".

If you want to sort on numerical value, you'll have to convert to int first.

1
2
3
4
5
6
7
8
int compare(const void *a, const void *b)
{
    struct s *ia = (struct s *)a;
    struct s *ib = (struct s *)b;
    int av = atoi( ia->a );  // string MUST be convertible to int!
    int bv = atoi( ib->a );  // string MUST be convertible to int!
    return av - bv;
}

Notice the caveat in there about the strings in s::a being convertible to int. If it is a possibility that they are not convertible, then use strtol() instead. See the documentation for both for more.

Hope this helps.
May 3, 2014 at 4:36pm
Thank you :)
Topic archived. No new replies allowed.