Comment obtenez-vous une liste de répertoire en C?

Comment parsingz-vous un répertoire pour les dossiers et les fichiers en C? Il doit être multi-plateforme.

Ce qui suit imprimera les noms des fichiers dans le répertoire courant:

#include  #include  #include  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; } 

(crédit: http://www.gnu.org/software/libtool/manual/libc/Simple-Directory-Lister.html )

La réponse ssortingcte est “vous ne pouvez pas”, car le concept même de dossier n’est pas vraiment multi-plateforme.

Sur les plates-formes MS, vous pouvez utiliser _findfirst, _findnext et _findclose pour une sorte de «c» et FindFirstFile et FindNextFile pour les appels Win32 sous-jacents.

Voici la réponse C-FAQ:

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

J’ai créé un en-tête open source (BSD) C qui traite de ce problème. Il supporte actuellement POSIX et Windows. Vérifie s’il te plaît:

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); 

Il n’y a pas de méthode C (ou C ++) standard pour énumérer les fichiers dans un répertoire.

Sous Windows, vous pouvez utiliser les fonctions FindFirstFile / FindNextFile pour énumérer toutes les entrées d’un répertoire. Sous Linux / OSX, utilisez les fonctions opendir / readdir / closedir.

GLib est une bibliothèque de portabilité / utilitaire pour C qui constitue la base du kit d’outils graphique GTK +. Il peut être utilisé comme bibliothèque autonome.

Il contient des wrappers portables pour la gestion des répertoires. Voir la documentation de Glib File Utilities pour plus de détails.

Personnellement, je ne penserais même pas à écrire de grandes quantités de code C sans quelque chose comme GLib derrière moi. La portabilité est une chose, mais il est également intéressant d’obtenir gratuitement des structures de données, des aides de threads, des événements, des Mainloops, etc.

Jikes, je commence presque à ressembler à un vendeur 🙂 (ne t’inquiète pas, glib est open source (LGPL) et je ne suis pas affilié de quelque façon que ce soit)

opendir / readdir sont des POSIX. Si POSIX n’est pas suffisant pour la portabilité que vous souhaitez atteindre, cochez Apache Portable Runtime.

La liste des répertoires varie considérablement en fonction du système d’exploitation / de la plate-forme en question. En effet, plusieurs systèmes d’exploitation utilisant leurs propres appels internes pour y parvenir.

Une solution à ce problème serait de chercher une bibliothèque qui masque ce problème et portable. Malheureusement, aucune solution ne fonctionne parfaitement sur toutes les plates-formes.

Sur les systèmes compatibles POSIX, vous pouvez utiliser la bibliothèque pour y parvenir en utilisant le code publié par Clayton (qui est référencé à l’origine par le livre Advanced Programming under UNIX de W. Richard Stevens). Cette solution fonctionnera sous les systèmes * NIX et fonctionnera également sous Windows si Cygwin est installé.

Vous pouvez également écrire un code pour détecter le système d’exploitation sous-jacent, puis appeler la fonction de liste de répertoires appropriée qui contiendrait le moyen «approprié» de répertorier la structure de répertoires sous ce système d’exploitation.

La méthode la plus similaire à readdir utilise probablement la famille de fonctions _find peu connue.

Vous pouvez trouver le code exemple sur le lien wikibooks

 /************************************************************** * A simpler and shorter implementation of ls(1) * ls(1) is very similar to the DIR command on DOS and Windows. **************************************************************/ #include  #include  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; } 

Bien tard, mais devine que je ne peux pas me retenir …

En utilisant le int system(char*) C int system(char*) vous pouvez faire toutes sortes de choses via une interface C “portable”. Vous devrez charger l’application avec le langage spécifique au système (par exemple, Shell / Bash, DOS, PowerShell), mais au moins vous n’aurez pas besoin de lier des bibliothèques supplémentaires. ET, contrairement à dirent , vous pouvez faire toutes sortes de choses “indépendantes de la plate-forme” en l’utilisant.

Exemple de répertoires avec linux (principalement pseudo):

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