Comment lister des fichiers dans un répertoire dans un programme C?

88

J'essaye d'écrire un serveur ftp sur Linux. Dans cette affaire, comment puis-je lister les fichiers dans le répertoire sur le terminal par un programme C? Peut-être que je peux utiliser la fonction exec pour exécuter la commande find mais je veux que le nom de fichier soit une chaîne pour envoyer le programme client. Comment puis-je faire ceci?

Merci pour les réponses.

cemal
la source

Réponses:

175

Un exemple, disponible pour les systèmes compatibles 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);
}

Attention, une telle opération dépend de la plate-forme en C.

Source: http://faq.cprogramming.com/cgi-bin/smartfaq.cgi?answer=1046380353&id=1044780608

Jean-Bernard Jansen
la source
c'est ok maintenant et si facile. Merci encore pour la réponse.
cemal
13
veuillez le valider si vous l'avez aimé;)
Jean-Bernard Jansen
1
Génial, mais que faire si nous ne voulons que des pngfichiers?
Farsheed
2
@Farsheed: essayez ceci .
Fraxtil
Je rencontre peu de problèmes avec cela. Première, "." et ".." apparaissent en haut de chaque répertoire, et bien qu'il s'agisse de "répertoires", ils ont le dir-> d_type mis à DT_REG. Aussi, je ne semble pas obtenir tous les fichiers ... Y a-t-il quelque part un code "scanner de répertoire" plus complet? Peut-être une implémentation de "ls" pour les pauvres? J'en ai besoin sur Mac - OS-X
Motti Shneor
35

Un petit ajout à la réponse de JB Jansen - dans la readdir()boucle principale, j'ajouterais ceci:

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

Il suffit de vérifier s'il s'agit vraiment d'un fichier, pas d'un lien (sym), d'un répertoire ou autre.

REMARQUE: plus d'informations struct direntdans la libcdocumentation .

Kamiccolo
la source
6
Juste un aparté: toutes les plates-formes ne se rempliront pas d_type, mais Linux et BSD le feront (je sais que la question est étiquetée Linux, étendant juste un peu la réponse); même dans ce cas, tous les systèmes de fichiers ne sont pas pris en charge de manière uniforme , mais cela devrait fonctionner avec la plupart des FS.
omninonsense
11

Voici un programme complet pour lister de manière récursive le contenu d'un dossier:

#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
la source
4

Le code ci-dessous n'imprimera que les fichiers dans le répertoire et exclura les répertoires dans le répertoire donné lors de la traversée.

#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);     
}
Joie
la source