Lister les fichiers d'un répertoire.

Fonction permettant de naviguer dans les repertoires, trouver tous les fichiers, les dossiers, parcourir le disque.

_findfirst,_findnext,_chdir

Voir version :

Pas de dépendances

Télécharger :

#include <stdio.h>
#include <stdlib.h>
#include <io.h>
#include <direct.h>

void dir()
{
    struct _finddata_t D;
    int done=0;
    int hd;
    hd = _findfirst("*.*",&D);
    if (hd==-1)
        return;
    while (!done) 
    {
        printf("%s\n",D.name);
        done = _findnext(hd,&D);
    }
}

void dirS()
{
    struct _finddata_t D;
    int done=0;
    int hd;
    hd = _findfirst("*.*",&D);
    if (hd==-1)
        return;
    while (!done) 
    {
        if (D.name[0]!='.')
        {
            if (D.attrib&0x10)
            {
                printf("Entree Repertoire %s\n",D.name);
                _chdir(D.name);
                dirS();
                printf("Sortie Repertoire %s\n",D.name);
                _chdir("..");
            }
            else
                printf("%s\n",D.name);
        }
        done = _findnext(hd,&D);
    }
}

int main()
{
    dir();
    //dirS();
    return 0;
}



Commentaires

Tutorial UNIQUEMENT pour personnes averties et d'un niveau correct en C/C++.

------------------------> ATTENTION !!!!!!!!!!!!!!!!!!!!! <---------------------------------


Note : TOUT CE QUE VOUS TROUVEREZ DANS CE CHAPITRE PEUT ETRE DANGEREUX.
Merci de veiller a ce que vous faites : si vous ne vous sentez pas d'attaque, arretez tout !
En effet, parcourir votre disque, en soi, ne sera pas dangereux, mais si vous décidez d'écrire, d'effacer, etc...
et que par mégarde vous procédez dans + de "sous repertoires" que prévu, vous pouvez massacrer votre disque dur.
(les donénées qu'il y a dessus, pas de dommages physique)
Je me dégage de toute responsabilité, tout ce que je promet, c'est que les programmes que je propose ne sont pas dangereux.
Si vous les modifiez, je ne réponds de rien.
Autant pour les autres rubriques, je vous encourage a tester d'autres choses, autant ici, c'est différent, méfiez vous.

Réfléchissez avant de continuer.

---------------------------------------------------------------------------------------------	


Voici comment manipuler l'arborescence des fichiers.

Dans un premier temps, constatez que seul la fonction dir() est appelée, pas la fonction dirS()

Le programme est simple : il liste les fichiers du répertoire courant.

Alors que fait la fonction dir :

elle crée une structure _finddata_t :

vous indiquez d'abord un _findfirst qui va renvoyer un identifiant de recherche hd,
et surtout remplir la structure _finddata_t
Si hd est égal à -1, c'est qu'il n'y a pas de fichiers correspondant à votre recherche dans le répertoire courant

_findfirst trouve le premier fichier du répertoire courant du type passé, et remplit la structure.

(note, ici je passe *.* qui veut dire : tous les fichiers. Si je passe *.cpp je liste que les fichiers cpp)
(se référer a la doc MSDOS ou la doc SHELL_UNIX pour comprendre comment ça marche...)

Cette structure contient toutes les données sur le fichier trouvé :

Voici sa définition :

struct _finddata_t {
unsigned    attrib;
time_t      time_create;
time_t      time_access;
time_t      time_write;
_fsize_t    size;
char        name[260];
};

avec :
typedef long time_t;
typedef unsigned long _fsize_t;

vous naviguez dedans comme une autre structure.

Le champ fondamental est le champ name qui donne le nom du fichier, c'est lui qu'on écrit dans l'exemple.
le champ size renvoie la taille en octets
les champs time* renvoient les dates associées.
le champ attribut renvoie un champ cumulable en OU binaire des valeurs suivantes :  (voir exemple sur les flags dans ce tuto pour l'utilisation des masques binaires)

#define _A_NORMAL       0x00
#define _A_RDONLY       0x01
#define _A_HIDDEN       0x02
#define _A_SYSTEM       0x04
#define _A_SUBDIR       0x10
#define _A_ARCH         0x20


vous savez ainsi si le fichier lu est un fichier ou un dossier par exemple, ou alors s'il est caché, system, lecture seule...

La commande _findnext passe au fichier suivant. Son utilisation est triviale.

Remplacez le dir() du main par un dirS()

le programme parcours maintenant les sous repertoires.
Il regarde si un fichier est de type sous-repertoire, si c'est le cas, il l'explore.

ATTENTION !!!!!!!!!!!!!

Vous le savez peut etre, ou peut etre pas, mais sous un systeme FAT ou NTFS (windows), ou UNIX (linux) il existe, dans chaque sous repertoires,
2 dossiers invisibles sous l'explorateur.
Ces dossiers ont comme nom :

. : (1 point) désigne le repertoire courant
et
.. : (2 points) désigne le repertoire précédent (repertoire pere)

findfirst et findnext les trouveront, et les verront donc comme des dossiers !
Dans mon programme test, je dis, par un test, que s'il est dessus, alors il ne fait rien.

Si je ne fais pas cela, alors, des qu'il trouve un .. il REMONTE AU REPERTOIRE DU DESSUS
Du coup, recursivement, il remonte A LA RACINE DU DISQUE
et donc il liste TOUT le disque dur...

C'est le piege classique, on est dans un repertoire, on veut faire une action sur ce qu'il y a en dessous,
et uniquement dessous, on lance la récursivité en oubliant d'enlever le repertoire ".." et du coup, la recursivité
remonte et traite TOUT le disque...

Pour le gars qui veut programmer un "Deltree" (programme qui détruit un repertoire), une telle erreur lui delete TOUT son disque....

A méditer...


-----------------------------

portabilité :
Il est possible que ce code ne marche que sous certains compilos (testé sous Visual C++)

Sous d'autres compilos/systemes, il est possible que les haeders a inclure ne soient pas les memes :
par exemple :
#include <nmake.h> 
#include <dir.h> 

et que les fonctions findfirst et findnext ne soient pas précédées de _
il est également possible que la structure _finddata_t  aie un autre nom.
Par exemple, sous Borland C++ : ffblk