2008-08-15 9 views

Répondre

5

opendir/readdir sont POSIX. Si Posix ne suffit pas pour la portabilité que vous voulez réaliser, vérifier Apache Portable Runtime

68

Les commandes suivantes impriment les noms des fichiers dans le répertoire courant:

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

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

+1

Cela devrait fonctionner sur Windows et, au moins avec MinGW. –

+1

@Clayton mais on m'a appris que n'utilise jamais puts() car il ne sait pas combien de caractères imprimer? – YakRangi

+0

Qu'en est-il: 'erreur: nom de type inconnu 'off64_t'' –

18

Le La réponse stricte est "vous ne pouvez pas", car le concept même d'un dossier n'est pas vraiment multi-plateforme.

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

Voici le C-FAQ réponse:

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

+0

est-il un alias déjà configuré pour _findfirst, _findnext et _findclose quelque part? pas dans windows.h pas vrai? – BuddyJoe

9

Il n'y a aucun moyen standard C (ou C++) 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.

+0

Boost :: système de fichiers ?? – paxos1977

+1

@ceretullis: Notez le mot "standard" .. Boost n'est pas encore standard .. – krebstar

+23

Boost n'est pas non plus C. –

2

La liste des répertoires varie considérablement en fonction du système d'exploitation/de la plate-forme considéré. C'est parce que, différents systèmes d'exploitation utilisent leurs propres appels système 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 dans le livre Advanced Programming under UNIX de W. Richard Stevens). Cette solution fonctionnera sous les systèmes * NIX et fonctionnera également sur Windows si vous avez installé Cygwin.

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 contiendra la manière «correcte» de répertorier la structure de répertoires sous ce système d'exploitation.

7

GLib est une bibliothèque de portabilité/utilitaire pour C qui constitue la base de la boîte à outils graphique GTK +. Il peut être utilisé comme une bibliothèque autonome.

Il contient des wrappers portables pour la gestion des répertoires. Voir la documentation Glib File Utilities pour plus de détails. Personnellement, je ne considérerais même pas écrire de grandes quantités de C-code sans quelque chose comme GLib derrière moi. La portabilité est une chose, mais il est également agréable d'obtenir gratuitement des structures de données, des threads helpers, des événements, etc ...

Jikes, je commence presque à ressembler à un vendeur :) (ne vous inquiétez pas, glib est open source (LGPL) et je ne suis pas affilié en aucune façon)

+2

+1; La fonction pertinente est 'g_dir_read_name()' – weiqure

13

J'ai créé un en-tête C (BSD) open source qui traite de ce problème. Il supporte actuellement POSIX et Windows. S'il vous plaît vérifier:

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

Comment cela aide-t-il plus que les implémentations dépendantes du système d'origine? Ou est-ce que vous n'avez besoin que d'une bibliothèque nommée pour Windows et POSIX? – kevr

+0

'Votez' pour tinydir.h, Bravo. –

-1

Vous pouvez trouver l'exemple de code sur la wikibooks link

/************************************************************** 
* 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; 
} 
Questions connexes