Jak wyświetlić listę plików w katalogu w programie C?

88

Próbuję napisać serwer ftp na Linuksie. W tej sprawie, jak mogę wyświetlić listę plików w katalogu na terminalu przez program C? Może mogę użyć funkcji exec, aby uruchomić polecenie find, ale chcę, aby nazwa pliku była ciągiem, aby wysłać program klienta. Jak mogę to zrobić?

Dzięki za odpowiedzi.

cemal
źródło

Odpowiedzi:

175

Przykład dostępny dla systemów zgodnych z POSIX:

/*
 * This program displays the names of all files in the current directory.
 */

#include <dirent.h> 
#include <stdio.h> 

int main(void) {
  DIR *d;
  struct dirent *dir;
  d = opendir(".");
  if (d) {
    while ((dir = readdir(d)) != NULL) {
      printf("%s\n", dir->d_name);
    }
    closedir(d);
  }
  return(0);
}

Uważaj, że taka operacja jest zależna od platformy w C.

Źródło: http://faq.cprogramming.com/cgi-bin/smartfaq.cgi?answer=1046380353&id=1044780608

Jean-Bernard Jansen
źródło
teraz jest ok i takie proste. Dzięki za odpowiedź ponownie.
cemal
13
proszę potwierdź to, jeśli ci się podobało;)
Jean-Bernard Jansen
1
Świetnie, ale co jeśli chcemy tylko pngplików?
Farsheed,
2
@Farsheed: spróbuj tego .
Fraxtil
Mam z tym kilka problemów. Pierwszy, "." i ".." pojawiają się na początku każdego katalogu i chociaż są to "katalogi", mają dir-> d_type ustawione na DT_REG. Poza tym wydaje mi się, że nie dostaję wszystkich plików ... Czy jest gdzieś bardziej wszechstronny kod „skanera katalogów”? Może jakaś implementacja ls dla biednych? Potrzebuję tego na Macu - OS-X
Motti Shneor,
35

Mały dodatek do odpowiedzi JB Jansena - w głównej readdir()pętli dodałbym to:

  if (dir->d_type == DT_REG)
  {
     printf("%s\n", dir->d_name);
  }

Po prostu sprawdzam, czy to naprawdę plik, a nie (sym) link, katalog lub cokolwiek innego.

UWAGA: więcej informacji struct direntw libcdokumentacji .

Kamiccolo
źródło
6
Na marginesie: nie wszystkie platformy zostaną wypełnione d_type, ale Linux i BSD tak (wiem, że pytanie jest oznaczone tagiem Linux, tylko trochę rozszerzę odpowiedź); nawet wtedy nie wszystkie systemy plików są obsługiwane jednolicie , jednak powinno działać z większością FS.
omninonsense
11

Oto kompletny program do rekurencyjnego wyświetlania zawartości folderu:

#include <dirent.h> 
#include <stdio.h> 
#include <string.h>

#define NORMAL_COLOR  "\x1B[0m"
#define GREEN  "\x1B[32m"
#define BLUE  "\x1B[34m"



/* let us make a recursive function to print the content of a given folder */

void show_dir_content(char * path)
{
  DIR * d = opendir(path); // open the path
  if(d==NULL) return; // if was not able return
  struct dirent * dir; // for the directory entries
  while ((dir = readdir(d)) != NULL) // if we were able to read somehting from the directory
    {
      if(dir-> d_type != DT_DIR) // if the type is not directory just print it with blue
        printf("%s%s\n",BLUE, dir->d_name);
      else
      if(dir -> d_type == DT_DIR && strcmp(dir->d_name,".")!=0 && strcmp(dir->d_name,"..")!=0 ) // if it is a directory
      {
        printf("%s%s\n",GREEN, dir->d_name); // print its name in green
        char d_path[255]; // here I am using sprintf which is safer than strcat
        sprintf(d_path, "%s/%s", path, dir->d_name);
        show_dir_content(d_path); // recall with the new path
      }
    }
    closedir(d); // finally close the directory
}

int main(int argc, char **argv)
{

  printf("%s\n", NORMAL_COLOR);

    show_dir_content(argv[1]);

  printf("%s\n", NORMAL_COLOR);
  return(0);
}
Faroq AL-Tam
źródło
4

Poniższy kod wydrukuje tylko pliki w katalogu i wykluczy katalogi w podanym katalogu podczas przeglądania.

#include <dirent.h>
#include <stdio.h>
#include <errno.h>
#include <sys/stat.h>
#include<string.h>
int main(void)
{
    DIR *d;
    struct dirent *dir;
    char path[1000]="/home/joy/Downloads";
    d = opendir(path);
    char full_path[1000];
    if (d)
    {
        while ((dir = readdir(d)) != NULL)
        {
            //Condition to check regular file.
            if(dir->d_type==DT_REG){
                full_path[0]='\0';
                strcat(full_path,path);
                strcat(full_path,"/");
                strcat(full_path,dir->d_name);
                printf("%s\n",full_path);
            }
        }
        closedir(d);
    }
    return(0);     
}
Radość
źródło