fonction parcourir des dossiers

fonction parcourir des dossiers - C - Programmation

Marsh Posté le 12-03-2013 à 14:44:44    

Bonjour, je suis en train de m'entrainer sur le c et j'ai un petit souci
je cherche a faire un programme qui liste les fichiers dans un dossier et qui les affiche a l'écran jusque la ca marche
mais maintenant il faut qu'il détecte si il y a un dossier et qu'il rentre dedans et affiche les nouveaux fichiers
 
Merci d'avance pour vos réponses
Voici le code :
 

Citation :

#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <dirent.h>
        /* Pour l'utilisation des dossiers */
#ifndef WIN32
#include <sys/types.h>
#endif
void ParcourirFichiers(char *daussier);
char *daussier;
 
            ParcourirDossier(char *dossier)
                {
 
            if ((strchr(dossier, '.')) == NULL) // Si le nom du fichier n'a pas de point (une extension).
            {
 
        dossier=daussier;
           }
void ParcourirFichiers(char *dossier);
 
                }
 
            ParcourirFichiers(char *dossier)
        {
        struct dirent *lecture;
    DIR *rep;
            rep = opendir(dossier);
                lecture=readdir(rep);
 
    while ((lecture=readdir(rep)) !=NULL)
    {
        printf("%s\n" , lecture->d_name);
 
    }
 
        }
 
main()
    {
 
ParcourirFichiers("C:\\TeSt" );
 
ParcourirDossier("C:\\TeSt" );
 
return 300;
    }

Reply

Marsh Posté le 12-03-2013 à 14:44:44   

Reply

Marsh Posté le 12-03-2013 à 15:40:12    

"char* daussier"
ça m'a tué ^^
 
Met nous un peu mieux en forme ton code, parce que là il y a des trucs bizarres:

Code :
  1. void ParcourirFichiers(char *daussier);
  2. char *daussier;
  3. ParcourirDossier(char *dossier) // ==============> une définition de fonction sans type?
  4. {
  5.     if ((strchr(dossier, '.')) == NULL) // Si le nom du fichier n'a pas de point (une extension).  
  6.     {
  7.         dossier=daussier;
  8.     }
  9.     void ParcourirFichiers(char *dossier);  // ==============> On re-déclare la fonction dans elle même? That's INCEPTION! :)
  10. }


 
 
Je te conseille de tester la valeur de retour de opendir() pour déterminer si l'entité est ou non un dossier
ex:

Code :
  1. DIR *rep = opendir(dossier);
  2. if(rep == 0)
  3. {
  4.     //C'est un fichier
  5. }
  6. else
  7. {
  8.     //rep est un dossier
  9. }


Message édité par crom29 le 12-03-2013 à 15:42:36

---------------
Mods: HAF922 | Shinobi XL White    GitHub     Admin de La Colère d'Aurile, serveur RP-Action Neverwinter Nights 2
Reply

Marsh Posté le 13-03-2013 à 08:46:56    

Je suis content que mon code t'ai amusé
 
Blague a part , J'ai éssayé de modifier mon code mais je n'y arrive toujours pas
 

Citation :


void ParcourirDossier(DIR *rep)  
{
 
 
}
 
 void ParcourirFichiers(char *dossier)
{
struct dirent *lecture;
    DIR *rep = opendir(dossier);
                lecture=readdir(rep);
 
    while ((lecture=readdir(rep)) !=NULL)
    {
        printf("%s\n" , lecture->d_name);
 
    }
    if(rep == 0)
        {
                    //C'est un fichier
        }
    else
        {      //la je suppose que je dois envoyer rep a ma fonction Parcourir dossier puisqu'il contient le chemin du dossier
              ParcourirDossier(DIR *rep)      //rep est un dossier
        }                                                  //apres je ne sait pas comment faire pour lire le chemin de rep dans la fonction cité plus haut..
        }


 
Voila merci pour ton aide (précédante et future)

Reply

Marsh Posté le 13-03-2013 à 08:47:39    

Et désolé pour le retard...

Reply

Marsh Posté le 13-03-2013 à 09:15:17    

Pas de soucis, je suis pas pressé ^^

 


Je dirais plutôt :

Code :
  1. void ParcourirFichiers(char *dossier)
  2. {
  3.     struct dirent *lecture;
  4.     DIR *rep = opendir(dossier);
  5.     lecture=readdir(rep);
  6.     while ((lecture=readdir(rep)) !=NULL)
  7.     {
  8.         //Pour chaque fichier (au sens large, donc fichier ou dossier)
  9.         //On essaye d'ouvrir le fichier comme si c'était un dossier
  10.         //  Dans la doc de opendir, on lit que la fonction renvoit un pointeur vers le dossier en cas de succes, et renvoit un pointeur nul sinon
  11.         DIR *newrep = opendir(dossier);
  12.         if(newrep == 0)//opendir a renvoyé un pointeur nul ==> il n'a pas réussi à ouvrir le dossier
  13.         {
  14.             //newrep est un fichier, on l'affiche
  15.             printf("Fichier:\t %s\n" , lecture->d_name);
  16.         }
  17.         else //opendir a renvoyé un pointeur vers un DIR ==> il a réussi à ouvrir le dossier
  18.         {
  19.             //newrep est donc un dossier
  20.             printf("Dossier:\t %s\n" , lecture->d_name);
  21.            
  22.             //On fait une récurrence pour re-executer la fonction sur ce dossier
  23.             //Je te laisse compléter ça ;)
  24.         }
  25.     }
  26. }

Note : je n'ai pas compilé le code


Message édité par crom29 le 13-03-2013 à 09:16:24

---------------
Mods: HAF922 | Shinobi XL White    GitHub     Admin de La Colère d'Aurile, serveur RP-Action Neverwinter Nights 2
Reply

Marsh Posté le 13-03-2013 à 10:44:45    

Normalement, on utilise de la récursivité pour ce type de fonction.
Il faut juste faire un cas spécial de . et .. retournés par readdir pour ne pas boucler à l'infini
D'autre part, on teste habituellement si on a un fichier ou un répertoire avec fstat/fstat64
 
Et le  
#ifndef WIN32  
#include <sys/types.h>  
#endif  
est insuffisant, il faudra tout réécrire pour windows, qui n'a pas de opendir/readdir... mais utilise FindFirstFile/FindFirstNext...
 
A+,


Message édité par gilou le 13-03-2013 à 10:45:39

---------------
There's more than what can be linked! --    Iyashikei Anime Forever!    --  AngularJS c'est un framework d'engulé!  --
Reply

Marsh Posté le 14-03-2013 à 09:07:46    

Je bloque encore : pour l'instant ma fonction affiche les fichier avec l'option dossier elle ne prend pas en compte le parametre fichier
 

Citation :

void ParcourirFichiers(char *dossier)
{
struct dirent *lecture;
    DIR *rep = opendir(dossier);
                lecture=readdir(rep);
 
    while ((lecture=readdir(rep)) !=NULL)
    {
        //Pour chaque fichier (au sens large, donc fichier ou dossier)
        //On essaye d'ouvrir le fichier comme si c'était un dossier
        /*  Dans la doc de opendir, on lit que la fonction renvoit un pointeur vers le dossier en cas de succes, et renvoit un pointeur
         nul sinon */
 
        DIR *newrep = opendir(dossier);
 
        if(newrep == 0)//opendir a renvoyé un pointeur nul ==> il n'a pas réussi à ouvrir le dossier
        {
                 while (strcmp(lecture->d_name, "." ) != 0 && strcmp(lecture->d_name, ".." ) != 0)
                 {
 
            //newrep est un fichier, on l'affiche
            printf("Fichier:\t %s\n" , lecture->d_name); // c'est ce paramètre la qui n'est pas pris en compte
                }
 
        }
        else //opendir a renvoyé un pointeur vers un DIR ==> il a réussi à ouvrir le dossier
        {
            //newrep est donc un dossierb
            printf("Dossier:\t %s\n" , lecture->d_name);
 
            //On fait une récurrence pour re-executer la fonction sur ce dossier
            //Je te laisse compléter ça ;)
void ParcourirDossier(DIR *newrep);
        }
    }
        }
 
main()
    {
 
ParcourirFichiers("C:\\TeSt" );
 
 
return 10;
    }


 
Je vais essayer de faire ce que gilou m'a dit avec fstat ... en espérant que cela reglera mes problèmes..

Reply

Marsh Posté le 14-03-2013 à 09:20:57    

Gilou est plus expérimenté que moi, il tiens certainement la clé ^^
 
Je te conseille de regarder un peu la récursivité, parce qu'il y a une belle erreur dans ton code:
http://franckh.developpez.com/tuto [...] cursivite/


---------------
Mods: HAF922 | Shinobi XL White    GitHub     Admin de La Colère d'Aurile, serveur RP-Action Neverwinter Nights 2
Reply

Marsh Posté le 14-03-2013 à 11:11:13    

L'algo récursif de base pour faire ce qu'il veut est très simple:
 
TraiteEntréeDossier(EntréeDossier entrée, Booléen toplevel)  
Si Fichier(entrée) alors Imprimer(Nom(entrée)) puis sortir. (FinSi)
Si Dossier(entrée) alors
   Si Nom(entrée) est '.' ou  '..' et toplevel est faux alors sortir (FinSi)
   Imprimer(Nom(entrée))
   ListeEntréesDossier listeentrées <- ListerEntréesDossier(entrée)
   Boucler sur élémentliste dans listeentrées
      TraiteEntréeDossier(élémentliste, Faux)  
   FinBoucler
FinSi
sortir
 
A+,
 
 
     
   


---------------
There's more than what can be linked! --    Iyashikei Anime Forever!    --  AngularJS c'est un framework d'engulé!  --
Reply

Marsh Posté le 14-03-2013 à 11:31:10    

J'ai tapé fstat, mais c'est stat que je voulais mentionner :/
Voici un exemple d'utilisation pour vérifier qu'un nom (complet ou local, selon le current working directory) est bien celui d'un dossier

Code :
  1. bool isDir(const char *name)
  2. {
  3.        struct stat stbuf;
  4.        if (stat(name, &stbuf) == -1) {
  5.            fprintf(stderr, "fsize: can't access %s\n", name);
  6.            return false;
  7.        }
  8.        return ((stbuf.st_mode & S_IFMT) == S_IFDIR);
  9.       /* si on remplace S_IFDIR par S_IFREG on teste pour un fichier normal,  
  10.           S_IFLNK pour un lien symbolique, S_IFSOCK pour une socket, etc. */
  11. }


 
La solution que tu as envisagée, appeler opendir(dossier) et vérifier que l'on a une erreur de type ENOTDIR ou pas n'est pas mauvaise à la base, mais je ne sais pas dans quelle mesure elle est efficace
 
A+,


Message édité par gilou le 14-03-2013 à 13:19:16

---------------
There's more than what can be linked! --    Iyashikei Anime Forever!    --  AngularJS c'est un framework d'engulé!  --
Reply

Marsh Posté le 14-03-2013 à 11:31:10   

Reply

Marsh Posté le 14-03-2013 à 11:46:02    

merci pour les informations mais j'ai encore une question quelles librairies (je ne sait pas si c'est comme ca que je dois l'appeler) doit-je inclure pour stat ?

Reply

Marsh Posté le 14-03-2013 à 11:48:46    

#include <sys/stat.h>
Cela fait des appels système Unix, donc a priori, pas besoin de linker avec une librairie spéciale il me semble.
A+,


Message édité par gilou le 14-03-2013 à 11:52:14

---------------
There's more than what can be linked! --    Iyashikei Anime Forever!    --  AngularJS c'est un framework d'engulé!  --
Reply

Marsh Posté le 16-03-2013 à 18:08:30    

Voila pour l'instant je tourne en rond
j'ai essayé de refaire mon code et pour l'instant il y a toujours des erreurs
 

Citation :

#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <stdbool.h>
#include <dirent.h>
#ifndef WIN32
#include <sys/types.h>
#endif
 
 
bool isDir(const char *dossier)
{
           struct stat stbuf;      // j'ai une erreur a ce niveau : la taille de stbuf est inconnue
           if (stat(dossier, &stbuf) == -1) {
               fprintf(stderr, "fsize: can't access %s\n", dossier);
               return false;
           }
           return ((stbuf.st_mode & S_IFMT) == S_IFDIR);
}
 
 
 
void ParcourirFichiers(char *dossier)
{
struct dirent *lecture;
    DIR *rep = opendir(dossier);
                lecture=readdir(rep);
 
            while ((lecture=readdir(rep)) !=NULL)
    {
        if (strcmp(lecture->d_name, "." ) != 0 && strcmp(lecture->d_name, ".." ) != 0)
                printf("%s\n", lecture->d_name);
 
            bool isDir(dossier);
    }
 
}
 
main()
    {
 
ParcourirFichiers("C:\\TeSt" );
 
 
return 10;
    }

 
 
Et je ne sait pas comment faire pour que la fonction isdir ouvre ce dossier ainsi que ce que je dois vraiment changer dans cette fonction...
merci d'avance pour l'aide future...

Reply

Marsh Posté le 16-03-2013 à 19:31:55    

Citation :

// j'ai une erreur a ce niveau : la taille de stbuf est inconnue

Et mon post précédent, il sert à quoi?
 

Citation :

bool isDir(dossier);

ça, à cet endroit la, ça veut rien dire du tout, faut peut être réfléchir un minimum.
 
A+,


---------------
There's more than what can be linked! --    Iyashikei Anime Forever!    --  AngularJS c'est un framework d'engulé!  --
Reply

Marsh Posté le 18-03-2013 à 14:07:03    

Bon j'ai enfin réussi a finir mon programme  
 
Et merci gilou et crom29 de m'avoir aidé
Voila le code pour les prochains qui voudront faire pareil :

Citation :


#define _XOPEN_SOURCE 500
#include <unistd.h>
#include <sys/stat.h>
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <stdbool.h>
#include <dirent.h>
#ifndef WIN32
#include <sys/types.h>
#endif
 
 
 
int is_dir(char *dossier)
{
 DIR *is_folder=NULL;
 
 is_folder=opendir(dossier);
 if (is_folder!=NULL){
  closedir(is_folder);
  return 1;
 }
 
 closedir(is_folder);
 return 0;
 
}
 
void ParcourirFichiers(char *dossier)
{
struct dirent *lecture;
    DIR *rep = opendir(dossier);
                lecture=readdir(rep);
                char chemin_temp[500] = "";
 
            while ((lecture=readdir(rep)) !=NULL)
            {
                if (strcmp(lecture->d_name, "." ) != 0 && strcmp(lecture->d_name, ".." ) != 0)
                {
                    strcpy(chemin_temp,dossier);
                    strcat(chemin_temp,"\\" );
                    strcat(chemin_temp,lecture->d_name);
 
 
                    if( is_dir(chemin_temp) == 1)
                    {
                        printf("====== dossier : %s \n\n",lecture->d_name);
                        ParcourirFichiers(chemin_temp);
                    }
                    else
                    {
                        printf("- %s\n",lecture->d_name);
                    }
                }
            }
 
}
 
int main(void)
    {
char chaine_chemin[100] = "";
 
printf("(Arborescence complete)quel chemin voulez vous examiner ?\n" );
scanf("%s",&chaine_chemin);
 
 
ParcourirFichiers(chaine_chemin);
 
//ParcourirFichiers("C:\\TeSt" );
 
 
return 10;
 
system("pause" );
    }

Reply

Marsh Posté le 18-03-2013 à 16:45:13    

Bonjour,
Juste pour dire que sous windows un chemin peut faire jusqu'à MAX_PATH caractères de long et il me semble que cette valeur vaut dans les 260. ( http://msdn.microsoft.com/en-us/li [...] 85%29.aspx section "Maximum Path Length Limitation" )
Si tu explores les sous-dossiers et que l'arborescence est profonde, tu risques de planter ton programme avec strcat qui risque de concaténer un chemin beaucoup plus grand que tes 100 caractères de char chaine_chemin[100] .
J'imagine que c'est valable aussi sous linux... (edit: c'est encore pire: http://fixunix.com/questions/14623 [...] linux.html )


Message édité par breizhbugs le 18-03-2013 à 16:48:53

---------------
Seul Google le sait...
Reply

Marsh Posté le 18-03-2013 à 17:21:37    

En plus, les systèmes anciens étaient parfois buggés.
Sur un unix je pouvais créér des répertoires récursivement et dépasser la taille autorisée à une époque (30 ans). :D
A+,


---------------
There's more than what can be linked! --    Iyashikei Anime Forever!    --  AngularJS c'est un framework d'engulé!  --
Reply

Marsh Posté le 18-03-2013 à 20:08:51    

Il semblerait que ce soit compliqué en effet: http://insanecoding.blogspot.fr/20 [...] -isnt.html
 
Sinon pour windows si le MAX_PATH est de 260 caractères, certaines fonctions unicode (d'après la doc msdn de mon précédent message) permettent des chemins de ~32767 caractères....


---------------
Seul Google le sait...
Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed