Linux программирование в примерах
Шрифт:
scandir
читает каталог, имя которого дано в dir
, создает с использованием malloc
массив указателей struct dirent
и устанавливает *namelist
, чтобы он указывал на начало этого массива. Как массив указателей, так и указываемые структуры struct dirent
выделяются с помощью malloc
; вызывающий код должен использовать free
, чтобы избежать утечек памяти. Для выбора нужных элементов используйте указатель функции
select
. Когда это значение равно NULL
, все действительные элементы каталога включаются в конечный массив. В противном случае (*select)
вызывается для каждого элемента, и те элементы, для которых она возвращает ненулевое (истинное) значение, включаются в массив. Указатель функции compare сравнивает два элемента каталога. Он передается функции
qsort
для использования при сортировке. alphasort
лексикографически сравнивает имена файлов. Она использует для сравнения функцию strcoll
. strcoll
похожа на strcmp
, но учитывает связанные с местной спецификой правила сортировки (см. раздел 13.4 «Не могли бы вы написать это для меня по буквам?»). versionsort
является расширением GNU, которое использует для сравнения имен файлов функцию GNU strverscmp
(см. strverscmp(3).) Короче говоря, эта функция понимает обычные соглашения по версиям имен файлов и сравнивает их соответствующим образом. В
ch06-sortdir.c
приведена программа, похожая на ch04-catdir.c
. Однако, она использует для работы scandir
и alphasort
.
1 /* ch06-sortdir.c --- Демонстрирует scandir, alphasort. */
2
3 #include <stdio.h> /* для printf etc. */
4 #include <errno.h> /* для errno */
5 #include <sys/types.h> /* для системных типов */
6 #include <dirent.h> /* для функций каталогов */
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
программы (строки 1–27) следует стандартному шаблону, который мы использовали до этого. Функция nodots
(строки 31–35) действует как параметр select
, выбирая лишь имена файлов, которые не начинаются с точки. Функция
process
(строки 43–65) довольно проста, причем scandir
делает большую часть работы. Обратите внимание, как каждый элемент отдельно освобождается с помощью free
(строка 59) и как освобождается также весь массив (строка 62). При запуске содержимое каталога в самом деле выводится в отсортированном порядке, без '
.
' и '..
'.
$ ch06-sortdir /* Действия по умолчанию отображают текущий каталог */
2097176 00-preface.texi
2097187 01-intro.texi
2097330 02-cmdline.texi
2097339 03-memory.texi
2097183 03-memory.texi.save
2097335 04-fileio.texi
2097334 05-fileinfo.texi
Поделиться:
Популярные книги
Черный Маг Императора 12
12. Черный маг императора
Фантастика:
юмористическое фэнтези
попаданцы
аниме
сказочная фантастика
фэнтези
5.00
рейтинг книги
Император Пограничья 10
10. Император Пограничья
Фантастика:
городское фэнтези
аниме
фантастика: прочее
попаданцы
5.00
рейтинг книги
Мастер...
1. Мастер
Фантастика:
героическая фантастика
попаданцы
аниме
6.50
рейтинг книги
Гранит науки. Том 2
2. Героями не становятся, ими умирают
Фантастика:
фэнтези
5.00
рейтинг книги
Адепт. Том 1. Обучение
6. Совсем не герой
Фантастика:
фэнтези
9.27
рейтинг книги
Тактик
2. Офицер
Фантастика:
альтернативная история
7.70
рейтинг книги
Ст. сержант. Назад в СССР. Книга 5
5. Второй шанс
Фантастика:
попаданцы
альтернативная история
5.00
рейтинг книги
Рассвет русского царства. Книга 2
2. Новая Русь
Фантастика:
альтернативная история
попаданцы
историческое фэнтези
5.00
рейтинг книги
Надуй щеки! Том 2
2. Чеболь за партой
Фантастика:
попаданцы
дорама
фантастика: прочее
5.00
рейтинг книги
Черный Маг Императора 18
18. Черный маг императора
Фантастика:
юмористическое фэнтези
аниме
сказочная фантастика
фэнтези
фантастика: прочее
попаданцы
5.00
рейтинг книги
Последний Паладин. Том 3
3. Путь Паладина
Фантастика:
юмористическое фэнтези
попаданцы
аниме
5.00
рейтинг книги
Воин
2. Совсем не герой
Фантастика:
фэнтези
попаданцы
9.25
рейтинг книги
Неправильный лекарь. Том 4
4. Неправильный лекарь
Фантастика:
городское фэнтези
попаданцы
альтернативная история
аниме
5.00
рейтинг книги
Кодекс Охотника. Книга VI
6. Кодекс Охотника
Фантастика:
фэнтези
попаданцы
аниме
5.00