Как вывести названия всех файлов для каталога и его подкаталогов в Linux?

Нужно в Linux на языке Си для каталога (считывается с клавиатуры) и его подкаталогов, вывести названия всех файлов. Как это можно сделать ?


Ответы (1 шт):

Автор решения: avp

Вот пример нерекурсивной программы, которая сканирует дерево каталогов, используя scandir.

Общая идея состоит в том, что мы берем имена каталогов из очереди, в которую же помещаем все новые встречающиеся в процессе сканирования (и печати содержимого каталога) каталоги. Т.е. реализуется т.н. просмотр дерева "в ширину".

#define _DEFAULT_SOURCE  // необходимо для заполнения .d_type в результатах scandir
#include <dirent.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>


#define ADDQ(q, cap, n, str) ({ \
      if (n == cap)                                                     \
        if ((q = realloc(q, (cap += 100) * sizeof(char *))) == 0) {     \
          perror("realloc");                                            \
          exit(EXIT_FAILURE);                                           \
        }                                                               \
      q[n++] = strdup(str);                                             \
    })


int
main (int ac, char *av[])
{
  char path[PATH_MAX];
  int qcap = 0;
  int qn = 0;
  char **q_dir = 0;

  fputs("Enter dir: ", stdout);
  if (scanf("%s", path) != 1)
    return 1;
  ADDQ(q_dir, qcap, qn, path);
  int te = 0;

  for (int i = 0; i < qn; i++) {
    struct dirent **namelist;
    int n = scandir(q_dir[i], &namelist, NULL, alphasort);
    if (n == -1) {
      perror("scandir");
      exit(EXIT_FAILURE);
    }

    printf("Content %s:\n", q_dir[i]);
    for (int j = 0; j < n; j++) {
      printf("%s\n", namelist[j]->d_name);
      te++;
      
      if (strcmp(namelist[j]->d_name, ".") == 0 ||
          strcmp(namelist[j]->d_name, "..") == 0)
        continue;

      if (namelist[j]->d_type == DT_DIR) {
        snprintf(path, PATH_MAX, "%s/%s", q_dir[i], namelist[j]->d_name);
        ADDQ(q_dir, qcap, qn, path);
      }

      free(namelist[j]);
    }

    free(namelist);
  }

  printf("total dirs: %d (enries %d)\n", qn, te);
  for (int i = 0; i < qn; i++)
    free(q_dir[i]);
  free(q_dir);

  return 0;
}

Что конкретно будет не понятно, спрашивайте (но сначала прочтите релевантные manpages).

→ Ссылка