Как получить список каталогов в C?

Как сканировать каталог на наличие папок и файлов в C? Он должен быть кроссплатформенным.

10 ответов

  1. Следующая программа POSIX напечатает имена файлов в текущем каталоге:

    #define _XOPEN_SOURCE 700
    #include <stdio.h>
    #include <sys/types.h>
    #include <dirent.h>
    
    int main (void)
    {
      DIR *dp;
      struct dirent *ep;     
      dp = opendir ("./");
    
      if (dp != NULL)
      {
        while (ep = readdir (dp))
          puts (ep->d_name);
    
        (void) closedir (dp);
      }
      else
        perror ("Couldn't open the directory");
    
      return 0;
    }
    

    Кредит: http://www.gnu.org/software/libtool/manual/libc/Simple-Directory-Lister.html

    Протестировано в Ubuntu 16.04.

  2. Строгий ответ: «вы не можете», так как сама концепция папки не является действительно кроссплатформенной.

    На платформах MS можно использовать _findfirst, _findnext и _findclose для типа «c», а findfirstfile и FindNextFile для базовых вызовов Win32.

    Вот ответ C-FAQ:

    http://c-faq.com/osdep/readdir.html

  3. Нет стандартного способа перечисления файлов в каталоге на языке C (или c++).

    В Windows можно использовать функции FindFirstFile/FindNextFile для перечисления всех записей в каталоге. В Linux / OSX используйте функции opendir/readdir / closedir.

  4. Список каталогов сильно варьируется в зависимости от рассматриваемой ОС/платформы. Это происходит потому, что различные операционные системы, используя свои собственные внутренние системные вызовы, чтобы достичь этого.

    Решение этой проблемы было бы искать библиотеку, которая маскирует эту проблему и переносима. К сожалению, нет решения, которое работает на всех платформах безупречно.

    В системах, совместимых с POSIX, вы можете использовать библиотеку для достижения этой цели, используя код, опубликованный Clayton (на который первоначально ссылается из книги W. Richard Stevens «Advanced Programming Unix»). это решение будет работать под * NIX систем, а также будет работать на Windows, Если у Вас установлен Cygwin.

    Кроме того, можно написать код для обнаружения базовой ОС, а затем вызвать соответствующую функцию листинга каталогов, которая будет содержать «правильный» способ листинга структуры каталогов под этой ОС.

  5. GLib-это библиотека переносимости/утилиты для C, которая является основой графического инструментария GTK+. Его можно использовать как автономную библиотеку.

    Он содержит портативные оболочки для управления каталогами. Подробнее см. В документации Glib File Utilities.

    Лично я даже не рассматривал бы написание больших объемов C-кода без чего-то вроде GLib позади меня. Переносимость одно, но также славно получить структуры данных, помощников потока, случаи, mainloops etc. бесплатно

    Jikes, i’M almost starting to sound like a sales guy 🙂 (не волнуйтесь, glib is open source (LGPL) and i’m not affiliated with it in any way)

  6. Я создал заголовок c открытым исходным кодом (BSD), который имеет дело с этой проблемой. В настоящее время он поддерживает POSIX и Windows. Пожалуйста, проверьте это:

    https://github.com/cxong/tinydir

    tinydir_dir dir;
    tinydir_open(&dir, "/path/to/dir");
    
    while (dir.has_next)
    {
        tinydir_file file;
        tinydir_readfile(&dir, &file);
    
        printf("%s", file.name);
        if (file.is_dir)
        {
            printf("/");
        }
        printf("\n");
    
        tinydir_next(&dir);
    }
    
    tinydir_close(&dir);
    
  7. Пример кода можно найти по ссылке wikibooks

    /**************************************************************
     * A simpler and shorter implementation of ls(1)
     * ls(1) is very similar to the DIR command on DOS and Windows.
     **************************************************************/
    #include <stdio.h>
    #include <dirent.h>
    
    int listdir(const char *path) 
    {
      struct dirent *entry;
      DIR *dp;
    
      dp = opendir(path);
      if (dp == NULL) 
      {
        perror("opendir");
        return -1;
      }
    
      while((entry = readdir(dp)))
        puts(entry->d_name);
    
      closedir(dp);
      return 0;
    }
    
    int main(int argc, char **argv) {
      int counter = 1;
    
      if (argc == 1)
        listdir(".");
    
      while (++counter <= argc) {
        printf("\nListing %s...\n", argv[counter-1]);
        listdir(argv[counter-1]);
      }
    
      return 0;
    }
    
  8. Очень поздно, но, думаю, я не могу держать себя.

    Используя Cint system(char*), вы можете делать все виды вещей через «портативный» C-интерфейс. Вы должны были бы загрузить приложение с конкретным системным языком (например, Shell/Bash, DOS, PowerShell), но, по крайней мере, вам не нужно будет связывать дополнительные библиотеки. И, в отличие отdirent, вы можете делать все виды «независимых от платформы» вещей, используя его.

    Пример листинга каталогов с linux (в основном псевдо):

    system("ls . > some_file_or_pipe_or_whatever") //
    fscanf(file_or_pipe_or_whatever, "%s", a_line_from_ls);