As noted in the comments, the main answer is 'carefully'. The question itself doesn't say anything about sorting the content of the arrays. However, that is mentioned in one of the comments. Here's code that does the job, using the standard library function qsort() — twice. I extended the list of arrays a bit, and renamed arr6 to list to separate it from the other arrN arrays (and there is probably a better name for it than list — be my guest).
I called this qs79.c:
/* SO 4335-0957 */
#include <stdio.h>
#include <stdlib.h>
void sort_arr(int num, int **list);
void print_arr(int num, int **list);
int main(void)
{
int arr1[] = { 3, 9, 6, 7 };
int arr2[] = { 2, 5, 5 };
int arr3[] = { 0 };
int arr4[] = { 1, 6 };
int arr5[] = { 4, 5, 6, 2, 1 };
int arr6[] = { 4, 2, 7, 1, 5 };
int arr7[] = { 4, 2, 5, 1, 6 };
int arr8[] = { 9, 12, 19, 18, 10, 28, 27, 15, 15, 27 };
int arr9[] = { 4, 2, 5, 1, 5 };
int *list[] = { arr1, arr2, arr3, arr4, arr5, arr6, arr7, arr8, arr9 };
enum { NUM_LIST = sizeof(list) / sizeof(list[0]) };
printf("Unsorted:\n");
print_arr(NUM_LIST, list);
sort_arr(NUM_LIST, list);
printf("Sorted:\n");
print_arr(NUM_LIST, list);
return 0;
}
static int cmpintasc(const void *v1, const void *v2)
{
int i1 = *(int *)v1;
int i2 = *(int *)v2;
return (i1 > i2) - (i1 < i2);
}
#if 0
static inline int min(int x, int y) { return (x < y) ? x : y; }
static int cmpintptrasc(const void *v1, const void *v2)
{
int *i1 = *(int **)v1;
int *i2 = *(int **)v2;
int max = min(i1[0], i2[0]) + 1;
for (int i = 1; i < max; i++)
{
if (i1[i] != i2[i])
return (i1[i] > i2[i]) - (i1[i] < i2[i]);
}
return (i1[0] > i2[0]) - (i1[0] < i2[0]);
}
#endif
static int cmpintptrasc(const void *v1, const void *v2)
{
int *i1 = *(int **)v1;
int *i2 = *(int **)v2;
return (i1[0] > i2[0]) - (i1[0] < i2[0]);
}
void sort_arr(int num, int **list)
{
/* Sort each array in turn */
for (int k = 0; k < num; k++)
qsort(&list[k][1], list[k][0], sizeof(list[k][0]), cmpintasc);
/* Sort the whole list */
qsort(list, num, sizeof(list[0]), cmpintptrasc);
}
void print_arr(int num, int **list)
{
for (int k = 0; k < num; k++)
{
printf("%d: [%d] ", k, list[k][0]);
for (int c = 1; c < (list[k][0] + 1); c++)
printf("%d ", list[k][c]);
printf("\n");
}
}
When compiled and run, it produces:
Unsorted:
0: [3] 9 6 7
1: [2] 5 5
2: [0]
3: [1] 6
4: [4] 5 6 2 1
5: [4] 2 7 1 5
6: [4] 2 5 1 6
7: [9] 12 19 18 10 28 27 15 15 27
8: [4] 2 5 1 5
Sorted:
0: [0]
1: [1] 6
2: [2] 5 5
3: [3] 6 7 9
4: [4] 1 2 5 5
5: [4] 1 2 5 6
6: [4] 1 2 5 7
7: [4] 1 2 5 6
8: [9] 10 12 15 15 18 19 27 27 28
The version commented out with #if 0 … #endif does a more complicated comparison. It sorts the arrays so that the ones with the smallest numbers at the start of the array appear first, and then for those arrays which have a common subset, the shorter array comes before the longer:
Unsorted:
0: [3] 9 6 7
1: [2] 5 5
2: [0]
3: [1] 6
4: [4] 5 6 2 1
5: [4] 2 7 1 5
6: [4] 2 5 1 6
7: [9] 12 19 18 10 28 27 15 15 27
8: [4] 2 5 1 5
Sorted:
0: [0]
1: [4] 1 2 5 5
2: [4] 1 2 5 6
3: [4] 1 2 5 6
4: [4] 1 2 5 7
5: [2] 5 5
6: [1] 6
7: [3] 6 7 9
8: [9] 10 12 15 15 18 19 27 27 28
This was why the extra entries with near identical contents were added.
arr6should be sorted? Then carefully apply that criteria so that the pointers are shuffled into the correct sequence. I've seen that data before — the first entry in the individual arrays is the number of the other entries in that array. Do you need to sort each component array before sorting the array of arrays?sizeof(arr6)is the size of the (decayed) pointer parameter, not of the initital array. When passing an array to a function, you should usually pass the size with it.