I have this to sort a string array (argv itself) in two ways with qsort. i started with the linux man 3 qsort example. There cmpstringp is only one line:
/* The actual arguments to this function are "pointers to
pointers to char", but strcmp(3) arguments are "pointers
to char", hence the following cast plus dereference */
return strcmp(*(const char **) p1, *(const char **) p2);
I tried to reformulate this and it compiles without warnings only with
char *const* sp1 = vep1
i.e. const belongs in the middle - it is the argv entry (?). At least that is what qsort declaration demands. The above cast from man page seems different and complicated.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
/* vep: void pointer to elements being qsorted
sp: string pointer (char **) */
int
cmpstringp(const void *vep1, const void *vep2) {
char *const *sp1 = vep1,
*const *sp2 = vep2;
return strcmp(*sp1, *sp2);
}
/* Make char* from void*, and even char */
int
cmpchar(const void *p1, const void *p2) {
const char *cp1 = p1,
*cp2 = p2;
char c1 = *cp1,
c2 = *cp2;
if (c1 == c2)
return 0;
else
return c1 > c2 ? 1 : -1;
}
/* Sort cmd line args in two ways with qsort */
int main(int argc, char **argv) {
/* sort chars of each string */
for (int i = 1; i < argc; i++)
qsort(argv[i], // base / first
strlen(argv[i]), 1, // n_elems, elem_size
cmpchar);
/* sort argv strings 1 to argc-1 */
qsort(argv + 1,
argc - 1, sizeof *argv,
cmpstringp);
for (int j = 1; j < argc; j++)
puts(argv[j]);
return 0;
}
The second cmp function cmpchar has one extra assignment level. Without there would be just some harmless stars like if (*cp1 == *cp2).
How do I sort the elements of argv in C? has a solution like man page, with a cast directly in strcmp().
But isn't my cast-free approach more correct? I got warnings until I put the const where it belongs.