readdir, readdir_r, meme probleme

Le
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 une fonction
realisant un printf sur chaque entrs 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 t 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 = 1;
while(de = readdir(d->stream)) {
printf("-- DEBUG : fichier %d : %s", i, de->d_name);
i++;
}

ou cela (readdir_r - l j'ai galr mais fini par trouver !) :

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


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

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

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

open_dir(dir1);

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

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

close_dir(dir1);
return 1;
}


je pense que c'est, comme d'habitude, une erreur 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 dans le sens o mes connaissances
sont encore et malheureusement plutot limites, l'image de ce probleme
stupide !

merci,
julien.
Vos réponses
Gagnez chaque mois un abonnement Premium avec GNT : Inscrivez-vous !
Trier par : date / pertinence
Yves ROMAN
Le #617567

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()

omnikron
Le #617565
On Wed, 28 Apr 2004 16:38:20 +0200
Yves ROMAN

| 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
Yves ROMAN
Le #617563


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()

omnikron
Le #617561
On Wed, 28 Apr 2004 18:42:24 +0200
"Antoine Leca"
| >> 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
Publicité
Poster une réponse
Anonyme