Après s'être intéressés à errno, nous allons pouvoir coder des choses intéressantes.

Maintenant que l'on sait ouvrir et fermer un répertoire, pourquoi n'irait-on pas regarder ce qui se trouve dedans ?
La fonction readdir
C'est sûrement la fonction la plus importante du tutoriel.

Voyons son prototype :
Code : C | struct dirent* readdir(DIR* repertoire) ;
|
readdir() prend en paramètre un pointeur sur DIR ; ça, vous connaissez.
Par contre elle renvoie... un pointeur sur une structure dirent.
Eh bien cette structure, elle
simule le fichier du dossier qui sera lu ! C'est une structure qui est également définie dans dirent.h.

D'ailleurs, encore un peu d'
english :
dirent signifie
DIRectory ENTity, qui signifie entité de répertoire, qui signifie : c'est l'objet que contient un répertoire (dossier, fichiers...).
Pour ne pas vous embrouiller avec le mot entité, j'emploierai le terme de fichier, mais ne faites pas de confusions avec les FILE*.
readdir() renvoie NULL s'il n'y a plus de fichier à lire.
Vous voulez du code ? Parfait. Ce code permet de lire le premier fichier d'un répertoire (je vous passe les directives de préprocesseur) :
Code : C 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15 | int main()
{
DIR* rep = NULL;
struct dirent* fichierLu = NULL; /* Déclaration d'un pointeur vers la structure dirent. */
rep = opendir("D:\\Mes Documents\\JaKy");
if (rep == NULL)
exit(1);
fichierLu = readdir(rep); /* On lit le premier répertoire du dossier. */
if (closedir(rep) == -1)
exit(-1);
return 0;
}
|
Après l'appel de readdir, le pointeur de structure
fichierLu pointe vers le premier répertoire du dossier JaKy !
Le mot-clé struct me gêne ! J'ai essayé de l'enlever et j'ai une erreur de compilation : dirent undeclared...
En effet, les développeurs n'ont pas fait de typedef à cette structure. Néanmoins, je suis persuadé que vous savez le faire.
Lister le contenu d'un répertoire
C'est bien joli d'utiliser readdir mais... comment savoir quel est le nom du fichier qui est lu ?
C'est bien simple : la structure dirent contient une variable membre, une chaîne de caractères précisément, appelée
d_name, qui contient le nom de notre fichier !
Code : C | fichierLu = readdir(rep);
printf("Le fichier lu s'appelle '%s'", fichierLu->d_name); /* On utilise la flèche
car fichierLu est un POINTEUR de structure. */
|
Résultat :
Code : Console | Le fichier lu s'appelle '.' |
Gné ? Pourquoi on a droit à un point ?
Le point représente le dossier actuel, celui dans lequel on se trouve ! Si vous connaissez la commande cd, alors :
Code : Bash
Ceci devrait vous éclairer l'esprit.
Je vous propose maintenant de continuer à lire notre répertoire. On va donc rajouter une 2
e fois la fonction readdir().
Code : C | fichierLu = readdir(rep);
printf("Le fichier lu s'appelle '%s'\n", fichierLu->d_name);
fichierLu = readdir(rep);
printf("Le fichier lu s'appelle '%s'", fichierLu->d_name);
|
Code : Console | Le fichier lu s'appelle '.'
Le fichier lu s'appelle '..' |
Les deux points représentent le dossier précédent, le dossier qui
contient celui dans lequel on se trouve.
Continuons encore un peu. Comme nous voulons lister TOUT le répertoire, il va donc falloir utiliser une boucle qui lira le fichier
tant que l'on n'est pas à la fin du dossier... autrement dit,
tant que notre fichier est différent de NULL, je l'avais précisé juste avant.
Code : C | while ((fichierLu = readdir(rep)) != NULL)
printf("Le fichier lu s'appelle '%s'\n", fichierLu->d_name);
|
Normalement vous devriez reconnaître la syntaxe de la boucle while() dans le TP du Pendu et dans l'annexe sur la saisie sécurisée. On lit le répertoire tant qu'il y a quelque chose à lire, et on affiche le nom.
Ouvrir un fichier
O.K., maintenant, on sait lire et afficher le contenu de tout le répertoire. Afficher, c'est bien beau, mais pas très utile, alors pourquoi ne pas charger quelque chose, comme un fichier .txt ou un .jpg par exemple ?
La plupart des fonctions permettant de charger une ressource (comme
SDL_LoadBMP (de SDL) pour les .bmp,
FSOUND_Sample_Load (de FMOD) pour un .mp3, ou même opendir

) attendent, comme argument, une chaîne de caractères qui elle-même contient le nom de la ressource à charger.
Quelle coïncidence ! La variable membre de la structure dirent est aussi une chaîne de caractères !
Conclusion : pour charger quelque chose, il suffit juste de passer en paramètre
d_name.
Code : C | /* Imaginons que d_name = "image.bmp" */
img = SDL_LoadBMP(fichierLu->d_name);
|
Si vous utilisez des chemins absolus, vous
devez créer une nouvelle chaîne assez grande contenant C:\Program Files\ + leNomDuFichier par exemple, car d_name contient seulement le nom du fichier lu et
PAS son arborescence.