scandir()
dir, создает с использованием malloc() массив указателей struct dirent и устанавливает *namelist, чтобы он указывал на начало этого массива. Как массив указателей, так и указываемые структуры struct dirent выделяются с помощью malloc(); вызывающий код должен использовать free(), чтобы избежать утечек памяти.Для выбора нужных элементов используйте указатель функции select
NULL, все действительные элементы каталога включаются в конечный массив. В противном случае (*select)() вызывается для каждого элемента, и те элементы, для которых она возвращает ненулевое (истинное) значение, включаются в массив.Указатель функции compare сравнивает два элемента каталога. Он передается функции qsort()
alphasort()
strcoll(). strcoll() похожа на strcmp(), но учитывает связанные с местной спецификой правила сортировки (см. раздел 13.4 «Не могли бы вы написать это для меня по буквам?»).versionsort()
strverscmp() (см. В ch06-sortdir.c
ch04-catdir.c. Однако, она использует для работы scandir() и alphasort().1 /* ch06-sortdir.c --- Демонстрирует scandir(), alphasort(). */
2
3 #include
4 #include
5 #include
6 #include
7
8 char *myname;
9 int process(const char *dir);
10
11 /* main --- перечислить аргументы каталога */
12
13 int main(int argc, char **argv)
14 {
15 int i;
16 int errs = 0;
17
18 myname = argv[0];
19
20 if (argc == 1)
21 errs = process("."); /* по умолчанию текущий каталог */
22 else
23 for (i = 1; i < argc; i++)
24 errs += process(argv[i]);
25
26 return (errs != 0);
27 }
28
29 /* nodots --- игнорирует файлы с точкой, для scandir() */
30
31 int
32 nodots(const struct dirent *dp)
33 {
34 return (dp->d_name[0] != '.');
35 }
36
37 /*
38 * process --- сделать что-то с каталогом, в данном случае,
39 * вывести в стандартный вывод пары индекс/имя.
40 * Вернуть 0, если все нормально, в противном случае 1.
41 */
42
43 int
44 process(const char *dir)
45 {
46 DIR *dp;
47 struct dirent **entries;
48 int nents, i;
49
50 nents = scandir(dir, &entries, nodots, alphasort);
51 if (nents < 0) {
52 fprintf(stderr, "%s: scandir failed: %s\n", myname,
53 strerror(errno));
54 return 1;
55 }
56
57 for (i = 0; i < nents; i++) {
58 printf("%81d %s\n", entries[i]->d_ino, entries[i]->d_name);
59 free(entries[i]);
60 }
61
62 free(entries);
63
64 return 0;
65 }
Функция main()
nodots() (строки 31–35) действует как параметр select, выбирая лишь имена файлов, которые не начинаются с точки.Функция process()
scandir() делает большую часть работы. Обратите внимание, как каждый элемент отдельно освобождается с помощью free() (строка 59) и как освобождается также весь массив (строка 62).При запуске содержимое каталога в самом деле выводится в отсортированном порядке, без '.
..'.