[C] Lister les fichiers d un repertoire

Lister les fichiers d un repertoire [C] - C - Programmation

Marsh Posté le 22-04-2005 à 16:15:25    

Il y a t il une methode simple de lister les fichiers situer dans un repertoire en les triant par date.
Je suis en C sous bash.
 
Merci

Reply

Marsh Posté le 22-04-2005 à 16:15:25   

Reply

Marsh Posté le 22-04-2005 à 16:30:41    

sbucci2 a écrit :

Il y a t il une methode simple de lister les fichiers situer dans un repertoire en les triant par date.


Faut le faire soi même. Rien de standard C. opendir()/readdir() est POSIX.1. Pour le tri, qsort() est standard.  

Citation :

Je suis en C sous bash.


Ca veut dire que ton C est interprété ?


Message édité par Emmanuel Delahaye le 22-04-2005 à 16:31:09

---------------
Des infos sur la programmation et le langage C: http://www.bien-programmer.fr Pas de Wi-Fi à la maison : http://www.cpl-france.org/
Reply

Marsh Posté le 22-04-2005 à 16:34:26    

je vais regarder les fonctions que tu m as donné.
 
Je compile normalement avec mon make et ensuite j execute.

Reply

Marsh Posté le 22-04-2005 à 16:36:03    

J'ajouterais que tu auras surement besoin de la fonction "stat()" pour avoir accès à la date du fichier, pour pouvoir ensuite le trier.

Reply

Marsh Posté le 22-04-2005 à 16:42:59    

Avec ca tes fichiers sont triés et affichés du plus ancien au plus recent
 

Code :
  1. #include <stdio.h>
  2. #include <sys/types.h>
  3. #include <dirent.h>
  4. int main()
  5. {
  6.     struct dirent *lecture;
  7.     DIR *rep;
  8.     rep = opendir("." );
  9.     while ((lecture = readdir(rep))) {
  10.         printf("%s\n", lecture->d_name);
  11.     }
  12.     closedir(rep);
  13. }


---------------
-= RAK =-
Reply

Marsh Posté le 22-04-2005 à 16:47:02    

merci bcp pour ce code

Reply

Marsh Posté le 22-04-2005 à 16:47:52    

que dois je utiliser pour changer la methode de tri ?
Encore merci

Reply

Marsh Posté le 22-04-2005 à 16:50:09    

Rak111 a écrit :

Avec ca tes fichiers sont triés et affichés du plus ancien au plus recent


Par quel miracle ?
Pas de tableau, pas de tri... C'est de la magie ?
 


---------------
Des infos sur la programmation et le langage C: http://www.bien-programmer.fr Pas de Wi-Fi à la maison : http://www.cpl-france.org/
Reply

Marsh Posté le 22-04-2005 à 16:59:47    

en tout cas, c est qu il fait !!!

Reply

Marsh Posté le 22-04-2005 à 18:11:04    

sbucci2 a écrit :

en tout cas, c est qu il fait !!!


Non.


#include <stdio.h>
#include <sys/types.h>
#include <dirent.h>
#include <sys/stat.h>
#include <time.h>
 
int main (void)
{
   DIR *rep = opendir ("." );
 
   if (rep != NULL)
   {
      struct dirent *lecture;
 
      while ((lecture = readdir (rep)))
      {
         struct stat st;
 
         stat (lecture->d_name, &st);
         {
            /* Modified time */
            time_t t = st.st_mtime;
            struct tm tm = *localtime (&t);
            char s[32];
            strftime (s, sizeof s, "%d/%m/%Y %H:%M:%S", &tm);
 
            printf ("%-14s %s\n", lecture->d_name, s);
         }
      }
      closedir (rep), rep = NULL;
   }
   return 0;
}


 


.              12/03/2005 10:09:26
..             02/04/2004 18:53:04
conio.o        12/04/2005 21:50:24
frmwrk.o       20/04/2005 21:27:06
main.o         22/04/2005 18:09:10
donnees.txt    12/03/2005 10:09:26
out.txt.html   12/03/2005 10:25:40
essais.txt     18/03/2005 19:45:24
temp           22/03/2005 23:30:52
list.o         29/03/2005 22:00:18
sll.o          12/04/2005 22:58:28
tmp.dat        29/03/2005 22:07:48
stats.txt      30/03/2005 08:35:14
gramNonRec.txt 03/04/2005 22:13:18
readLP.o       11/04/2005 19:42:08
523Up~1.sql    11/04/2005 21:54:30
523Update.sql  11/04/2005 21:42:36
Projet1.exe    22/04/2005 18:09:10
log.txt        18/04/2005 23:20:12


---------------
Des infos sur la programmation et le langage C: http://www.bien-programmer.fr Pas de Wi-Fi à la maison : http://www.cpl-france.org/
Reply

Marsh Posté le 22-04-2005 à 18:11:04   

Reply

Marsh Posté le 22-04-2005 à 21:15:32    

Le cadre d'en bas représente les fichiers une fois triés ?
 
apparament ta modif marche pas très bien... le readdir() lit les fichiers du plus ancien au plus recent. Qu'est ce que tu veux y faire de plus ? c'est bien la réponse à la question qui était posée non ?


---------------
-= RAK =-
Reply

Marsh Posté le 22-04-2005 à 21:28:09    

Rak111 a écrit :

Le cadre d'en bas représente les fichiers une fois triés ?


Non, c'est la liste brute telle qu'elle est sortie par readdir() (Sous Windows 98 / Dev-C++). Je voulais illustrer le fait qu'elle n'était pas triée et que l'affirmation  

Citation :

"Avec ca tes fichiers sont triés et affichés du plus ancien au plus recent"


était fausse.

Citation :


apparament ta modif marche pas très bien...  


Je n'ai fait aucune 'modif'. Je n'ai fait que mettre en oeuvre la liste avec les dates de modifications. Je n'ai rien trié du tout, et visiblement l'ordre est imprévisible.

Citation :


le readdir() lit les fichiers du plus ancien au plus recent.  


C'est pas ce que je constate. C'est peut être vrai sur un certain système, mais pas partout en tout cas. Que dit la norme ?(POSIX.1)
 
Suite à cette question existentielle de la plus haute importance, j'ai ajouté un topic dans mes notes sur POSIX.1
 
http://mapage.noos.fr/emdel/notes.htm#posix
 
(commentaires bienvenus)


Message édité par Emmanuel Delahaye le 23-04-2005 à 12:31:52

---------------
Des infos sur la programmation et le langage C: http://www.bien-programmer.fr Pas de Wi-Fi à la maison : http://www.cpl-france.org/
Reply

Marsh Posté le 22-04-2005 à 23:27:30    

Me semblait que le readdir lisait les fichiers dans l'ordre de l'index, point barre. A priori, aucune notion de timestamp sur le readdir, ou alors j'ai zappé un truc.

Reply

Marsh Posté le 23-04-2005 à 09:03:49    

Elmoricq a écrit :

Me semblait que le readdir lisait les fichiers dans l'ordre de l'index, point barre. A priori, aucune notion de timestamp sur le readdir, ou alors j'ai zappé un truc.


readdir n'est qu'une fonction qui lit un répertoire; à savoir un fichier contenant la liste d'autres fichiers.
La fonction lit donc le répertoire tel qu'il est écrit. Si le répertoire a été créé puis rempli d'une traite, les fichiers affichés seront évidemment affichés par ordre de création puisque c'est aussi l'ordre de remplissage. En revanche, si le répertoire a été plusieurs fois modifié, avec effacement, renommage et recréation de fichiers, l'ordre de lecture par "readdir" sera très difficile à prévoir (d'où le raccourci syntaxique "imprévisible" utilisé par Emmanuel bien que ça ne le soit pas réellement)


---------------
Vous ne pouvez pas apporter la prospérité au pauvre en la retirant au riche.
Reply

Marsh Posté le 23-04-2005 à 16:41:58    

Sve@r a écrit :

readdir n'est qu'une fonction qui lit un répertoire; à savoir un fichier contenant la liste d'autres fichiers.
La fonction lit donc le répertoire tel qu'il est écrit. Si le répertoire a été créé puis rempli d'une traite, les fichiers affichés seront évidemment affichés par ordre de création puisque c'est aussi l'ordre de remplissage. En revanche, si le répertoire a été plusieurs fois modifié, avec effacement, renommage et recréation de fichiers, l'ordre de lecture par "readdir" sera très difficile à prévoir (d'où le raccourci syntaxique "imprévisible" utilisé par Emmanuel bien que ça ne le soit pas réellement)


 
Ce que je disais, mais en beaucoup plus clair que ce que j'ai écrit.  :jap:

Reply

Marsh Posté le 23-04-2005 à 19:42:35    

Elmoricq a écrit :

Ce que je disais, mais en beaucoup plus clair que ce que j'ai écrit.  :jap:


 
Vi, ça c'est mon truc pour paraître brillant en société
Je lis un truc, s'il est pas trop dur j'arrive à le comprendre puis je le réexplique en plus long  :D  :D


---------------
Vous ne pouvez pas apporter la prospérité au pauvre en la retirant au riche.
Reply

Marsh Posté le 25-04-2005 à 09:54:50    

Comment je peux faire alors pour trier mes fichiers par date ???

Reply

Marsh Posté le 25-04-2005 à 10:08:04    

sbucci2 a écrit :

Comment je peux faire alors pour trier mes fichiers par date ???


  • Créer un tableau de {nom, date[1]}  
  • Trier le tableau (qsort()) sur le critère date ()
  • Lister le tableau
  • Détruire le tableau

Ou  

  • Créer une liste chainée ordonnée (tri par insersion)
  • Lister
  • Détruire la liste


-------------------------------
[1] valeur native de type time_t donnée par stat()...


---------------
Des infos sur la programmation et le langage C: http://www.bien-programmer.fr Pas de Wi-Fi à la maison : http://www.cpl-france.org/
Reply

Marsh Posté le 28-04-2005 à 21:26:30    

Et sous Linux [:alarmclock133] ?

Reply

Marsh Posté le 28-04-2005 à 21:31:19    

Froozen a écrit :

Et sous Linux [:alarmclock133] ?

Pareil.  opendir() / readdir(), c'est du POSIX.1. Linux est compatible.
 


---------------
Des infos sur la programmation et le langage C: http://www.bien-programmer.fr Pas de Wi-Fi à la maison : http://www.cpl-france.org/
Reply

Marsh Posté le 28-04-2005 à 21:32:52    

Je me suis trompé de topic, je voulais demander comment récupérer sous linux le résultat d'une commande ( system("ps -aux" ) par exemple) dans un buffer :)

Reply

Marsh Posté le 28-04-2005 à 21:34:51    

Froozen a écrit :

Je me suis trompé de topic, je voulais demander comment récupérer sous linux le résultat d'une commande ( system("ps -aux" ) par exemple) dans un buffer :)


Rediriger :  
system("ps -aux > out.txt" );
 
ou avec popen()...
 
Je ne suis pas spécialiste de Linux...
 


---------------
Des infos sur la programmation et le langage C: http://www.bien-programmer.fr Pas de Wi-Fi à la maison : http://www.cpl-france.org/
Reply

Marsh Posté le 28-04-2005 à 21:37:04    

Voilà c'est noté "_popen" sous MSDN donc je voulais connaître l'équivalent sous Linux :) Le but c'était justement d'éviter de passer par un fichier texte ;)
 
Je vais donc essayer popen ! :jap:

Reply

Marsh Posté le 10-12-2005 à 19:05:16    

Bonjour à tous,
Me concernant j'ai un petit soucis semblable.
 
J'arrive à afficher la liste des fichiers présents dans un répertoire, hors maintenant j'aimerais stocker cette liste
dans un buffer (char* buff[]). Pas moyen de trouver les commandes :cry:  
 
Pourriez vous m'aider et compléter mon code ?
 

Code :
  1. /*Mon argument d'entré est argv1, le nom du répertoire à lister*/
  2. int  list_dir(char* argv1)
  3. {
  4. DIR *dir;
  5. struct dirent *p;
  6. char *fic = NULL;
  7. dir=opendir(argv1);
  8. while((p = readdir(dir))!=NULL)
  9. {
  10.         fic = p->d_name;
  11.         fprintf(stdout, " Nom fichier :%s \n", fic);
  12. }
  13. closedir(dir);
  14. return 0;
  15. }


 
merci

Reply

Marsh Posté le 10-12-2005 à 19:16:40    

doudoudetahiti a écrit :


J'arrive à afficher la liste des fichiers présents dans un répertoire, hors maintenant j'aimerais stocker cette liste
dans un buffer (char* buff[]). Pas moyen de trouver les commandes


 
Tu as déjà un fprintf(). Il suffit d'utiliser sprintf() avec un tableau de taille suffisante. Ensuite, faire une copie 'dynamique' (strdup(), par exemple) et stocker l'adresse dans un tableau de pointeur sur char suffisamment grand.
 
On peut aussi utliser temporairement une liste chainée qui évite de se poser la question de la taille, quitte à la transformer ensuite en tableau de char *, ce qui facilite les traitements et autres tris...
 
NOTA : strdup() est POSIX.
 


---------------
Des infos sur la programmation et le langage C: http://www.bien-programmer.fr Pas de Wi-Fi à la maison : http://www.cpl-france.org/
Reply

Marsh Posté le 11-12-2005 à 11:19:11    

Je ne vois pas du tout comment faire, moi j'aimerais enregistrer tous le noms des fichiers dans un tableau à deux dimensions, sa taille est donc variable et dépend du nombre de fichier.
sprintf renvoie la longueur de la chaine.  
 
Pour être clair, je veus parcourir un répertoire, et stocker les noms de ce répertoire.
De même, la difficulté est telle que, ne connaissant pas le nombre de fichier dans mon rpertoire ila va falloir réallouer la taille de mon char** dans chaque boucle.
 
Si je pouvais avoir un exemple de code pour mon problème, ce serait super sympa

Reply

Marsh Posté le 11-12-2005 à 11:31:58    

doudoudetahiti a écrit :

Je ne vois pas du tout comment faire, moi j'aimerais enregistrer tous le noms des fichiers dans un tableau à deux dimensions, sa taille est donc variable et dépend du nombre de fichier.


J'ai bien compris ce que tu voulais faire, mais non, je ne te donnerais pas d'exemple de code, parce que c'est toi qui vas trouver le tout seul. On va y passer la journée si il le faut mais je te garantis que tu vas y arriver.
 
Le but est de réaliser ceci (par exemple):  


      -
P -> |p|-> "hello"  
      -
     |p|-> "wild"  
      -
     |p|-> "world"  
      -
     |p|-> NULL  
      -


1er exo :  

  • Définir un pointeur de pointeur de char.
  • Définir une variable taille (disons 4 pour commencer)
  • Initaliser le pointeur avec l'adresse d'un tableau de pointeur sur char de cette taille alloué dynamiquement
  • initialisé chaque pointeur à NULL (NEW)
  • libèrer le tableau, remettre le pointeur à NULL.

Poste le code.

Message cité 1 fois
Message édité par Emmanuel Delahaye le 11-12-2005 à 11:40:11

---------------
Des infos sur la programmation et le langage C: http://www.bien-programmer.fr Pas de Wi-Fi à la maison : http://www.cpl-france.org/
Reply

Marsh Posté le 11-12-2005 à 11:36:29    

doudoudetahiti a écrit :

Je ne vois pas du tout comment faire, moi j'aimerais enregistrer tous le noms des fichiers dans un tableau à deux dimensions, sa taille est donc variable et dépend du nombre de fichier.
sprintf renvoie la longueur de la chaine.  
 
Pour être clair, je veus parcourir un répertoire, et stocker les noms de ce répertoire.
De même, la difficulté est telle que, ne connaissant pas le nombre de fichier dans mon rpertoire ila va falloir réallouer la taille de mon char** dans chaque boucle.
 
Si je pouvais avoir un exemple de code pour mon problème, ce serait super sympa


une liste chainee ?

Reply

Marsh Posté le 11-12-2005 à 11:46:49    

Voilà ce ue qj'ai fait, mais n'étant pas très fort en pointeur, jai un soucis de compilation.
 
Je déclare donc un tableau de pointeur qui va pointer sur plusieur chaine de caractère.
 
Avec la fonction sprintf je récupère le nome du fichier et strdup me permet de stocker le pointeur (qui pointe sur le fichier) dans mon tableau.
 
De plus, voici les erreurs qui me sont renvoyées
 
"main.c: Dans la fonction « list_dir »:
main.c:134: attention : implicit declaration of function `strdup'
main.c:134: attention : affectation transforme un entier en pointeur sans transtypage"
 
Que dois je corriger
 

Code :
  1. nt  list_dir(char* argv1)
  2. {
  3. int i=0;
  4. DIR *dir;
  5. struct dirent *p;
  6. char* fic = NULL;
  7. char* liste[MAX_FIC];
  8. dir=opendir(argv1);
  9. while((p = readdir(dir))!=NULL)
  10. {
  11. fic = p->d_name;
  12. sprintf(fic,"%c",MAX_CAR);
  13. /*mon erreur se situe ici*/
  14. *(liste+i)=strdup(fic);
  15. i++;
  16. }
  17. closedir(dir);
  18. return 0;
  19. }

Reply

Marsh Posté le 11-12-2005 à 11:58:08    

doudoudetahiti a écrit :

Je déclare donc un tableau de pointeur qui va pointer sur plusieur chaine de caractère.


Ok, tu ne veux pas suivre ma méthode, libre à toi.

Citation :


Avec la fonction sprintf je récupère le nom du fichier  


J'ai pas compris comment, et de toutes façons, ça ne sert à rien.  

Citation :


et strdup me permet de stocker le pointeur (qui pointe sur le fichier) dans mon tableau.


Non. strdup() permet de faire une copie dynamique (malloc()) de la chaine. Elle renvoie une adresse qui est stockée dans le tableau de pointeurs. Tu peux passer à strdup()  l'adresse du nom de fichier qui est dans la structure (p->d_name)

Citation :


De plus, voici les erreurs qui me sont renvoyées
 
"main.c: Dans la fonction « list_dir »:
main.c:134: attention : implicit declaration of function `strdup'
main.c:134: attention : affectation transforme un entier en pointeur sans transtypage"


Ben oui, il manque un prototype (<string.h>, si je me souviens bien).
 
Hum, tu cherches à faire quoi ici:

fic = p->d_name;
 sprintf(fic,"%c",MAX_CAR);


 

*(liste+i)


est une façon compliquée d'écrire  

liste[i]


d'autre part, il ne faut pas déborder du tableau. Si i vaut MAX_FIC, il faut arréter ou agrandir (on ne peut pas agrandir un tableau de taille fixe).


Message édité par Emmanuel Delahaye le 11-12-2005 à 12:17:22

---------------
Des infos sur la programmation et le langage C: http://www.bien-programmer.fr Pas de Wi-Fi à la maison : http://www.cpl-france.org/
Reply

Marsh Posté le 11-12-2005 à 12:14:45    

Citation :


Ben oui, il manque un prototype (<string.h>, si je me souviens bien).  


 
Je l'ai pourtant mise la libraire.
 

Citation :

Hum, tu cherches à faire quoi ici:  
 
 
fic = p->d_name;  
 sprintf(fic,"%c",MAX_CAR);  
 
 


 
Hummn je sai pas trop
 
je travaille dessus, j'envoie incéssament sous peu ma nouvelle version, merci encore de m'aider  :hello:  
 

Reply

Marsh Posté le 11-12-2005 à 12:19:20    

doudoudetahiti a écrit :

Citation :


Ben oui, il manque un prototype (<string.h>, si je me souviens bien).  


Je l'ai pourtant mise la libraire.


Tu parles du header <string.h> ?
 
http://www.linux-kheops.com/doc/ma [...] dup.3.html
 
Ok. Quelles sont tes options de compilation ?
 


Message édité par Emmanuel Delahaye le 11-12-2005 à 12:20:29

---------------
Des infos sur la programmation et le langage C: http://www.bien-programmer.fr Pas de Wi-Fi à la maison : http://www.cpl-france.org/
Reply

Marsh Posté le 11-12-2005 à 12:29:22    

je compile de la façon suivante :
 
gcc -ansi -Wall -o main main.c

Reply

Marsh Posté le 11-12-2005 à 12:33:34    

doudoudetahiti a écrit :

je compile de la façon suivante :
 
gcc -ansi -Wall -o main main.c


Ok. Retire le '-ansi', car strdup() n'est pas ANSI, mais POSIX.
 
Je conseille ceci :  

gcc -Wall -Wextra -O2 -o main main.c



Message édité par Emmanuel Delahaye le 11-12-2005 à 12:34:52

---------------
Des infos sur la programmation et le langage C: http://www.bien-programmer.fr Pas de Wi-Fi à la maison : http://www.cpl-france.org/
Reply

Marsh Posté le 11-12-2005 à 13:03:29    


 
 
 

Code :
  1. /*Voilà nouvelle version, et ça à lair de marcher, j'ai oublié strdup car trop compliqué*/
  2. int  list_dir(char* argv1)
  3. {
  4. int i=0;
  5. DIR *dir;
  6. int nb_fichier=0;
  7. struct dirent *p;
  8. char* fic = NULL;
  9. char **liste=NULL;
  10. liste=(char**)malloc(nb_fichier*sizeof(char*));
  11. liste[0]=(char*)malloc(MAX_FIC*sizeof(char));
  12. dir=opendir(argv1);
  13. while((p = readdir(dir))!=NULL)
  14. {
  15. nb_fichier++;
  16. for(i=0;i<nb_fichier;i++)
  17. {
  18.  liste=realloc(liste,nb_fichier*sizeof(char*));
  19. }
  20. liste[nb_fichier-1]=p->d_name;
  21. fprintf(stdout,"  %s\n",liste[nb_fichier-1]);
  22. }
  23. closedir(dir);
  24. return 0;
  25. }


 
bon maitenant va falloir gérer les sous répertoires.
Si je fais un test du genre, si (opendir d'un nom est vraie) // alors c un répertoire et là je fais un appel récursif de la fonction

Reply

Marsh Posté le 11-12-2005 à 13:50:21    

doudoudetahiti a écrit :

Code :
  1. /*Voilà nouvelle version, et ça à lair de marcher, j'ai oublié strdup car trop compliqué*/




Désolé de te dire que ton code ne fonctionne pas du tout. Pour éviter ça, je t'avais proposé une approche pas à pas. Tu n'en pas pas voulu, je ne sais plus quoi faire pour toi...


---------------
Des infos sur la programmation et le langage C: http://www.bien-programmer.fr Pas de Wi-Fi à la maison : http://www.cpl-france.org/
Reply

Marsh Posté le 11-12-2005 à 14:03:45    

Emmanuel Delahaye a écrit :

Désolé de te dire que ton code ne fonctionne pas du tout. Pour éviter ça, je t'avais proposé une approche pas à pas. Tu n'en pas pas voulu, je ne sais plus quoi faire pour toi...


 
Je propose une danse de la pluie.
 
Ca ne sert à rien, mais c'est distrayant.

Reply

Marsh Posté le 11-12-2005 à 14:44:45    

Emmanuel Delahaye a écrit :

On va y passer la journée si il le faut mais je te garantis que tu vas y arriver.


 
Ca, ça s'appelle "avoir la foi"  :D  :D  :D  

Reply

Marsh Posté le 11-12-2005 à 14:49:18    

Sve@r a écrit :

Ca, ça s'appelle "avoir la foi"  :D  :D  :D


J'ai confiance dans mon approche pas à pas, mais comme le gus ne veut en faire qu'à sa tête, qu'il se démerde...
 
Pour changer, je vais aller faire un peu de musique, tiens...


---------------
Des infos sur la programmation et le langage C: http://www.bien-programmer.fr Pas de Wi-Fi à la maison : http://www.cpl-france.org/
Reply

Marsh Posté le 11-12-2005 à 16:16:30    

ça marche très bien !
 

Citation :

J'ai confiance dans mon approche pas à pas, mais comme le gus ne veut en faire qu'à sa tête, qu'il se démerde...


 
Désole d'avoir choisis un autre chemin, mais je suis loins d'être un spécialiste en prog.
De plus, j'aurai bien voulus suivre tes indications, mais je n'étais pas du tout près à passer la journée dessus étant donné que ceci est une infime partie de mon projet que je dois rendre demain.
 
Cependant, j'y travaille toujours notamment sur l'appel récursif de la fonction lorsque que le nom du fichier enregistré est en fait un sous répertoire.
Je cherche donc à stocker à la suite de ma liste de stockage les fichiers qui sonr présents dans les sous répertoires.
 
Donc si tu changes  d'avis, ton aide et ton opinion sont la bienvenue.
 
merci encore
 

Reply

Marsh Posté le    

Reply

Sujets relatifs:

Leave a Replay

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