I'm learning C and I have this implementation to sort the files and folders, but this isn't case insensitive:
#include <dirent.h>
#include <stddef.h>
#include <stdlib.h>
#include <stdio.h>
int main(void) {
struct dirent **namelist;
int n;
n = scandir(".", &namelist, NULL, alphasort);
if (n < 0)
perror("scandir");
else {
printf("Inside else, n = %d\n", n);
while (n--) {
printf("%s\n", namelist[n]->d_name);
free(namelist[n]);
}
free(namelist);
}
}
And if I have a.txt, b.txt, C.txt and z.txt it will sort in this order: C.txt, a.txt, b.txt, z.txt. I want this to be sorted case insensitive like this: a.txt, b.txt, C.txt, z.txt
CodePudding user response:
scandir
is defined with this prototype:
int scandir(const char *restrict dirp,
struct dirent ***restrict namelist,
int (*filter)(const struct dirent *),
int (*compar)(const struct dirent **,
const struct dirent **));
The function alphasort
sorts the filenames in lexicographical order, hence case-sensitive order. If you want case insensitive sorting, use a different comparison function:
int alphasort_no_case(const struct dirent **a, const struct dirent **b) {
return strcasecmp((*a)->d_name, (*b)->d_name);
}
Both scandir
and strcasecmp
are POSIX functions: strcasecmp
is highly likely to be available on systems that support scandir
and defined in <strings.h>
.
Modifier version:
#include <dirent.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <strings.h>
int alphasort_no_case(const struct dirent **a, const struct dirent **b) {
return strcasecmp((*a)->d_name, (*b)->d_name);
}
int main(void) {
struct dirent **namelist;
int n;
n = scandir(".", &namelist, NULL, alphasort_no_case);
if (n < 0) {
perror("scandir");
} else {
printf("Inside else, n = %d\n", n);
while (n--) {
printf("%s\n", namelist[n]->d_name);
free(namelist[n]);
}
free(namelist);
}
return 0;
}