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

scandir

22 réponses
Avatar
matt
Bonjour,

J'utilise la fonction scandir pour lister un repertoire comme suit :

n = scandir(".", &filelist, 0, alphasort);

mais je voudrais mettre un filtre du style *.txt mais je ne vois pas
comment faire ?

Ca se passe au niveau du 3eme paramètres, un pointeur de fonction mais
pour la suite ???

Pourriez vous m'aider ?

Merci pour vos réponses,

Matt.

PS : si HS pouvez vous m'indiquer le bon groupe.

10 réponses

1 2 3
Avatar
Harpo
On Sat, 21 Apr 2007 17:19:50 +0200, matt wrote:

ok, mais je fais un strrchr donc on commence la recherche par la fin
donc c'est bon ?


Pouquoi tu veux faire une recherche alors que tu sais que le '.' doit se
situer 4 char avant la fin de la chaîne ?

--
SKILL (Simple Knowledge Inference Logic Language)
http://patrick.davalan.free.fr/skill-0/

Avatar
Harpo
On Sat, 21 Apr 2007 17:22:32 +0200, matt wrote:

Sachant que c'est moi qui maitrise l'écriture, donc le nom et
l'extension de mes fichiers donc la casse aussi.


Le problème n'est pas celui de la casse (drôle de traduction) qui est
anecdotique.
Pour moi, si on écrit en C, avec toutes les douleurs que cela
représente, c'est pour écrire des programme performants, même si les
fonctions sous-jacentes sont bien écrites il faut éviter de scanner des
chaînes de caractère, du moins pas plus qu'une fois.

--
SKILL (Simple Knowledge Inference Logic Language)
http://patrick.davalan.free.fr/skill-0/

Avatar
matt
Le Sat, 21 Apr 2007 14:56:25 +0200, matt a écrit:

Le troisième paramètre est une fonction qui sera apellée pour chaque
fichier. Dans cette fonction, tu dois regarder si le fichier est bien
un ..txt (comparaison du nom), et retourner 1 si c'est le cas, 0 sinon.
La strcture dirent passée en param à cette fonction contient le nom du
fichier, donc rien de bien compliqué.





Merci pour la reponse, voici donc la fonction qui me permet de filtrer
les "*.txt" :

#include <dirent.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>

int filter(const struct dirent *a)
{
char *name = strrchr(a->d_name, '.');

if(name == NULL)
return 0;

if(strcmp(name, ".txt") == 0)
return 1;

return 0;
}

int main()
{
struct dirent **filelist = NULL;
int n = 0, i = 0;

n = scandir(".", &filelist, filter, alphasort);
if (n < 0)
{
perror("SCANDIR");
exit(EXIT_FAILURE);
}

for(i= 0; i < n; i++)
{
printf("%sn", filelist[i]->d_name);
free(filelist[i]);
}

free(filelist);

exit(EXIT_SUCCESS);
}

qu'en penser vous ?

Matt...



et ceci :

int filter(const struct dirent *a)
{
int len = strlen(a->d_name);
const char *name = a->d_name;

if(len < 4)
return 0;

if(name[--len] == 't' && name[--len] == 'x' && name[--len] == 't' &&
name[--len] == '.')
return 1;

return 0;
}

matt.


Avatar
Bruno Piguet
On Sat, 21 Apr 2007 17:22:32 +0200, matt wrote:

Sachant que c'est moi qui maitrise l'écriture, donc le nom et
l'extension de mes fichiers donc la casse aussi.


Le problème n'est pas celui de la casse (drôle de traduction) qui est
anecdotique.


Autant que je sache, casse n'est pas une traduction. Ou du moins, pas
récente.

On trouve à plusieurs endroits sur Internet (par exemple :
http://fr.wikipedia.org/wiki/Casse_%28typographie%29 ou
http://www.deluxeavenue.com/typo_c.php)
l'information que, du temps du plomb, les caractères étaient rangés dans
des tiroirs ou des casiers : la casse.
les caractères les plus fréquemment utilisés, les minuscules, étaient à
portée de main, donc en « bas-de-casse », par opposition aux caractères
majuscules qui se trouvaient donc relégués en haut de casse.

Bruno.


Avatar
Harpo
On Sun, 22 Apr 2007 07:57:41 +0200, Bruno Piguet wrote:

Autant que je sache, casse n'est pas une traduction. Ou du moins, pas
récente.


En effet, le Lexis donne :
Casse : n. f.(it. cassa, caisse, lat. capsa; 1539)

On trouve à plusieurs endroits sur Internet (par exemple :
http://fr.wikipedia.org/wiki/Casse_%28typographie%29 ou
http://www.deluxeavenue.com/typo_c.php)
l'information que, du temps du plomb, les caractères étaient rangés dans
des tiroirs ou des casiers : la casse.
les caractères les plus fréquemment utilisés, les minuscules, étaient à
portée de main, donc en « bas-de-casse », par opposition aux caractères
majuscules qui se trouvaient donc relégués en haut de casse.


Merci pour toutes ces précisions, il est toujours bon de connaître
l'origine des mots que l'on utilise, maintenant j'utiliserai 'casse'.

D'ailleurs comme je suis HS, je me casse.

--
SKILL (Simple Knowledge Inference Logic Language)
http://patrick.davalan.free.fr/skill-0/

Avatar
Antoine Leca
matt wrote:
Merci pour la reponse, voici donc la fonction qui me permet de filtrer
les "*.txt" :

#include <dirent.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>

int filter(const struct dirent *a)
{
char *name = strrchr(a->d_name, '.');

if(name == NULL)
return 0;


Manque peut-être ici un test
if(name == a->d_name)
return 0;

car le fichier de nom ".txt" tout sec ne correspond probablement [ÀMHA] pas
à tes critères de recherche.


if(strcmp(name, ".txt") == 0)
return 1;

return 0;
}



Par ailleurs, tu pourrais ajouter un commentaire dans un coin pour te
souvenir que scandir() et alphasort() ne sont pas « standards » (absentes de
la norme POSIX-2001/XPG6 ; c'est un héritage BSD4.3)


Antoine


Antoine

Avatar
Antoine Leca
Xavier Roche wrote:
if (memcmp(name + len - 4, ".txt", 4)) return 1;


FOO.TXT ?


D'après le contexte, il est sur Unix. Si tu veux traiter ce problème, il
faudrait alors récupérer les options de montage du volume courant (pour
savoir si le système de fichiers distingue majuscule et minuscule, pardon
capitale et bas-de-casse)...


Antoine


Avatar
Antoine Leca
En news:462a2f22$0$27392$,
Harpo va escriure:
Pour moi, si on écrit en C, avec toutes les douleurs que cela
représente, c'est pour écrire des programme performants, même si les
fonctions sous-jacentes sont bien écrites il faut éviter de scanner
des chaînes de caractère, du moins pas plus qu'une fois.


Solution de Matt: strrchr()+strcmp() -> une lecture complète de la chaîne +
5 comparaisons de caractères

Solution de Harpo: strlen()+memcmp() -> une lecture complète de la chaîne +
4 comparaisons de caractères

Si on veut économiser une comparaison avec la solution de Matt, on peut
écrire

if(strcmp(name+1, "txt") == 0)

mais franchement, le gain (s'il existe) est extrêmement marginal, et on perd
largement en lisibilité ce que l'on peut gagner en rapidité.


Je sais que strrchr() est moins rapide que strlen(), mais la différence
n'est pas de l'ordre de grandeur d'une lecture complète (surtout avec les
processeurs modernes et leurs pipelines).


Antoine

Avatar
Antoine Leca
En news:f0d6a5$2vp$,
Xavier Roche va escriure:
Merci pour la reponse, voici donc la fonction qui me permet de
filtrer les "*.txt" :
char *name = strrchr(a->d_name, '.');
(..)

if(strcmp(name, ".txt") == 0)
return 1;


Humm..
foo.bar.txt
^


strrchr("foo.bar.txt", '.') pointe vers
^


Quelque chose comme:

for(s = a->d_name, dot = NULL ; *s != '' ; s++) {
if (*s == '.') {
dot = s;
}
}


C'est exactement ce que fait strrchr(), et c'est même probablement la
manière dont il est implémenté sur beaucoup de machines...

strchr() a en plus un break; (ou un return dot;)


Antoine


Avatar
Xavier Roche
strRchr("foo.bar.txt", '.') pointe vers


Ah oui euh, fatigué, j'avais juste un peu raté le double "r".

1 2 3