0

I'm attempting to sort an array of structs in a struct based on an int value. I've successfully sorted an array of structs but I'm guessing I'm passing a wrong value somewhere for the nested structs.

I just need the structs in the array sorted the value of a.

The structs are set up as:

struct s2{
    int a;
    int b;
};

struct s1{
    int c;
    struct s2 arr[10];
}

I have a compare function:

int comp(const void *a, const void *b){

    struct s1 *q1 = (struct s1 *)a;
    struct s1 *q2 = (struct s1 *)b;

    return(q1->arr->a - q2->arr->a); 
}

And I call qsort:

struct s1 myStruct; 
size_t theLen = sizeof(myStruct.arr) / sizeof(struct s2);
qsort(myStruct.arr, 10, theLen, comp);

For the input:

10, 5, 7, 20, 17, 9, 3, 11, 15, 1

I get output:

2147451181, 589824, 327680, 65536, 131072, 4, 5, 11, 15, 8

I'm guessing it may be something to do with how I declare the length?

Thanks!

The file line is:

10 5 7 20 17 9 3 11 15 1

myStruct.arr[i].a is filled from file input using fgets and sscanf:

fgets(t, sizeof(t), fp);
sscanf(t, "%d,...,%d", &myStruct.arr[0].a,...,&myStruct.arr[9].a); 

myStruct.arr[i].b is filled with a for loop:

for(int i = 0; i < 10; i++){
    myStruct.arr[i].b = i+1;
}

2 Answers 2

1

There are two mistakes with your code

  1. You are using q1->arr->a to compare where you should use q1->a (where q1 is of type const struct s2). This has also been explained by @GauravSehgal in his answer

  2. If you look at the third argument to qsort, it is acutally the size of each element to compare in bytes. But you have passed the number of elements. Change your call to -

    qsort(myStruct.arr, 10, sizeof(struct s2), comp);

and you should get the desired result.

There are some other points you need to take care of (pointed out by @Stargateur) -

  1. Declare q1 and q2 to be of type const struct s2*, because you do not want to discard the const qualifier.

  2. Do not cast a and b explicitly while assigning to q1 and q2 because they are of type const void* which auto-promotes to pointer of any const type.

Sign up to request clarification or add additional context in comments.

1 Comment

I will add that OP cast is wrong (and useless cause void const * is auto promote) because it's discard const qualifier: should be struct s2 const *q1 = a; struct s1 const *q2 = b;
1
qsort(myStruct.arr, 10, theLen, comp);

You are sorting myStruct.arr here where each element is of type struct s2.So your compare should be

int comp(const void *a, const void *b){

struct s2 *q1 = (struct s2 *)a;
struct s2 *q2 = (struct s2 *)b;

return(q1->a - q2->a); 
}

EDIT: the third parameter to qsort is the size of each element of array to be sorted.So it should be

qsort(myStruct.arr, theLen, sizeof(struct s2), comp);

2 Comments

This definitely makes more sense than what I had, but unfortunately, it's still giving random output: 4, 589824, 11, 65551, 131072, 65536, 5, 196608, 0, 17. I shouldn't say random... it's the same output every time.
You need to show your complete code where you are filling myStruct.arr

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.