Twitter iPhone pliant OnePlus 11 PS5 Disney+ Orange Livebox Windows 11

readdir, readdir_r, meme probleme

4 réponses
Avatar
omnikron
bonjour,

je suis entrain d'apprendre le C (linux et gcc) et j'aimerai lister le
contenu d'un repertoire. pour tester cela, j'ai cr=E9=E9 une fonction
realisant un printf sur chaque entr=E9s du repertoire :
print_dir_list(t_dir *d) ne renvoyant rien (pour l'instant).

mon type t_dir est definit comme cela :

typedef struct {
char *path;
DIR *stream;
int open;
} t_dir;

path contien le chemin du repertoire,
stream contient le flux apres ouverture du repertoire (NULL si avant),
open est 1 si le repertoire a =E9t=E9 ouvert, 0 sinon.

dans mon main() (present ci-dessous), j'initialise tout d'abord ma
variable dir1 en allouant une zone memoire avec malloc de la taille du
type t_dir puis je passe les champs path et stream a NULL et le champ
open a 0.

la fonction set_dir_path() met ensuite a jour le champ path de dir1.
puis, la fonction open_dir() ouvre le flux vers le repertoire (en fesant
un appel a opendir()), et passe le champ open de dir1 a 1;

l'affichage du listing du repertoire fonctionne parfaitement, en
utilisant readdir(), mais lors d'un 2eme appel, l'affichage ne produit
rien. je parcours alors le manuel de la libc (gnu) et conclut que
l'utilisation repetitive de readdir() engendre des erreurs. j'utilise
donc, comme le recommande le manuel, la fonction readdir_r(). mais
voila, je constate malheureusement que le probleme persiste... j'avoue
ne pas trop comprendre. dans les deux cas, l'adresse memoire de dir1 et
de dir1->stream avant chaque appel reste bien la meme.

pour information, ma fonction print_dir_list(t_dir *d) ressemblait a
ceci :

struct dirent *de;
int i =3D 1;
while(de =3D readdir(d->stream)) {
printf("-- DEBUG : fichier %d : %s\n", i, de->d_name);
i++;
}

ou cela (readdir_r - l=E0 j'ai gal=E9r=E9 mais fini par trouver !) :=20

struct dirent de;
struct dirent *res;
int i =3D 1;
while( (readdir_r(d->stream, &de, &res) =3D=3D 0) && (res !=3D NULL) ) {
printf("-- DEBUG : fichier %d : %s\n", i, de.d_name);
i++;
}


fonction main() du programme :
n'affiche rien apres printf("-- DEBUG : listing (2)\n"); :((

int main(void) {
t_dir *dir1 =3D init_dir();

set_dir_path(dir1, "/home/omnikron/music");
printf("-- DEBUG : dir1->path =3D %s\n", dir1->path);

open_dir(dir1);

printf("-- DEBUG : listing (1)\n");
print_dir_list(dir1);

printf("-- DEBUG : listing (2)\n");
print_dir_list(dir1);

close_dir(dir1);
return 1;
}


je pense que c'est, comme d'habitude, une erreur =E0 la co*... mais la je
seche vraiment ! je pense qu'en posant cette question ici je trouverai
qq personnes bien plus competentes que moi et qui pourront m'aiguiller
ou me donner une piste.

il est clair, que je pourrait lister le contenu une seule fois, le
mettre dans un tableau de (char *) et ensuite traiter on tableau. mais
j'aimerai cependant bien comprendre le pourquoi du comment, en esperant
que ce ne soit pas hyper compliqu=E9 dans le sens o=F9 mes connaissances
sont encore et malheureusement plutot limit=E9es, =E0 l'image de ce probleme
stupide !

merci,
julien.

4 réponses

Avatar
Yves ROMAN

bonjour,

je suis entrain d'apprendre le C (linux et gcc) et j'aimerai lister le
contenu d'un repertoire. pour tester cela, j'ai créé une fonction
realisant un printf sur chaque entrés du repertoire :
print_dir_list(t_dir *d) ne renvoyant rien (pour l'instant).

mon type t_dir est definit comme cela :

typedef struct {
char *path;
DIR *stream;
int open;
} t_dir;

[...]


l'affichage du listing du repertoire fonctionne parfaitement, en
utilisant readdir(), mais lors d'un 2eme appel, l'affichage ne produit
rien. je parcours alors le manuel de la libc (gnu) et conclut que
l'utilisation repetitive de readdir() engendre des erreurs. j'utilise
donc, comme le recommande le manuel, la fonction readdir_r(). mais
voila, je constate malheureusement que le probleme persiste... j'avoue
ne pas trop comprendre. dans les deux cas, l'adresse memoire de dir1 et
de dir1->stream avant chaque appel reste bien la meme.

pour information, ma fonction print_dir_list(t_dir *d) ressemblait a
ceci :

struct dirent *de;
int i = 1;
while(de = readdir(d->stream)) {
printf("-- DEBUG : fichier %d : %sn", i, de->d_name);
i++;
}

[...]


fonction main() du programme :
n'affiche rien apres printf("-- DEBUG : listing (2)n"); :((

int main(void) {
t_dir *dir1 = init_dir();

set_dir_path(dir1, "/home/omnikron/music");
printf("-- DEBUG : dir1->path = %sn", dir1->path);

open_dir(dir1);

printf("-- DEBUG : listing (1)n");
print_dir_list(dir1);

printf("-- DEBUG : listing (2)n");
print_dir_list(dir1);

close_dir(dir1);
return 1;
}



Si tu considère que les fonctions opendir() readdir() et closedir() (non
standard C)
sont comme fopen(), fread() et fclose(), tu vois que tu fais :
fopen()
fread() jusqu'à la fin du fichier
fread() jusqu'à la fin du fichier
fclose()
Il est normal que la 2ème série de readdir() sorte tout de suite car tu es déjà
à la fin du répertoire.

Il faudrait rajouter un rewinddir() avant les readdir() dans print_dir_list(),
ou , si ca n'existe pas, faire les opendir() et closedir() dans print_dir_list()

Avatar
omnikron
On Wed, 28 Apr 2004 16:38:20 +0200
Yves ROMAN wrote:


| Si tu considère que les fonctions opendir() readdir() et closedir()
| (non standard C)
| sont comme fopen(), fread() et fclose(), tu vois que tu fais :
| fopen()
| fread() jusqu'à la fin du fichier
| fread() jusqu'à la fin du fichier
| fclose()
| Il est normal que la 2ème série de readdir() sorte tout de suite car
| tu es déjà à la fin du répertoire.

ah ok je vois le probleme.


| Il faudrait rajouter un rewinddir() avant les readdir() dans
| print_dir_list(),
| ou , si ca n'existe pas, faire les opendir() et closedir() dans
| print_dir_list()

oui effectivement... mais plus haut tu dis que les focntion opendir,
closedir et cie ne sont standars C, mais a ce moment les quels devrais
je utiliser pour respecter au maximum les standars ? autre question,
lesquelles utiliserait tu toi si tu voulais faire mon truc ?

merci de ta reponse
Avatar
Yves ROMAN


oui effectivement... mais plus haut tu dis que les focntion opendir,
closedir et cie ne sont standars C, mais a ce moment les quels devrais
je utiliser pour respecter au maximum les standars ? autre question,
lesquelles utiliserait tu toi si tu voulais faire mon truc ?

Il n'y a pas de fonction standard C qui fasse ca.

Cela dit, ces fonctions (opendir, ...) sont standard POSIX (il me semble). En
tout cas, tu les trouvera sur la plupart des UNIX.
Pour du développement sous Windows, utiliser FindFirst(), FindNext()

Avatar
omnikron
On Wed, 28 Apr 2004 18:42:24 +0200
"Antoine Leca" wrote:

| >> Il faudrait rajouter un rewinddir()
| <couic>
| >> ou , si ca n'existe pas,
|
| Si si, ça existe, justement pour cela ;-)
|

bon bah... voila, probleme resolu !
je vous remercie tous les deux :)

bonne continuation a vous.
julien