Récupération d'un tableau de chaines de caractères [Résolu/Fermé]

Signaler
Messages postés
5
Date d'inscription
mercredi 26 novembre 2014
Statut
Membre
Dernière intervention
27 novembre 2014
-
Messages postés
5
Date d'inscription
mercredi 26 novembre 2014
Statut
Membre
Dernière intervention
27 novembre 2014
-
Bonjour,

Je souhaite récupérer les noms des fichiers et sous-dossiers d'un dossier à l'aide d'un tableau de chaînes de caractères. Pour cela, j'utilise une fonction prenant en argument le tableau qui devra être rempli et retournant le nombre d'éléments trouvés dans le dossier scanné.

Voici mon programme:

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

int FileRepList(char **file){
struct dirent *lecture;
DIR *rep;
int i = 0;

rep = opendir(".");

file = (char **) malloc(sizeof(rep) * sizeof(char *));

while ((lecture = readdir(rep))) {
//printf("%s\n", lecture->d_name);
if((strcmp(lecture->d_name, ".")!=0) && (strcmp(lecture->d_name, "..")!=0)){
file[i] = malloc(strlen(lecture->d_name));
strcpy(file[i], lecture->d_name);
i = i + 1;
}
}
closedir(rep);

return i;
}

int main()
{
char **file;
int nb = 0;
int i = 0;

file = (char **) malloc(8 * sizeof(char *));
file[i] = malloc(10);


nb = FileRepList(&file);


for(i=0;i<nb;i++){
printf("\nfile[%d]: %s", i, file[i]);
}

return 0;
}


En débuggant la fonction, je m'aperçois que le tableau est, en effet, bien rempli avec les noms mais je ne parviens pas à les afficher dans mon main.

Auriez-vous une astuce pour récupérer l'ensemble du tableau dans le main?

Merci d'avance.

4 réponses

Messages postés
39
Date d'inscription
mardi 8 mars 2011
Statut
Membre
Dernière intervention
9 février 2017
20
Là, on a programme qui écrabouille la mémoire de partout... Explications:

opendir renvoie un "stream" ; aucune information sur le nombre de fichiers trouvés. Il est donc impossible d'allouer la bonne taille pour file dès le début. Soit on prévoit une taille fixe mais en prenant soin de ne pas aller au-delà, soit on met en place le mécanisme qui va réallouer de la mémoire à chaque fois que nécessaire. Pas si simple. Dans le présent programme, on va écrire de la mémoire inconnue dès qu'il y a plus de 4 fichiers ((sizeof(rep) * sizeof(char *)) divisé par sizeof(char *)).


file[i] = malloc(strlen(lecture->d_name));
strcpy(file[i], lecture->d_name);

=> et le caractère nul de fin de chaîne alors ? Il n'est pas prévu; du coup strcpy va écraser un octet dans une zone inconnue. Il vaut mieux utiliser strdup:
file[i] = strdup(lecture->d_name);



Le main n'affiche pas le tableau car la fonction FileRepList effectue:
file = ...

au lieu de quelque chose comme :
*file = ...



Bref, la fin n'est pas encore proche...
Messages postés
5
Date d'inscription
mercredi 26 novembre 2014
Statut
Membre
Dernière intervention
27 novembre 2014

J'ai revu mon programme pour parvenir à cela:

int FileRepList(char ***file){
struct dirent *lecture;
DIR *rep;
char *temp;
int i = 0;

rep = opendir(".");

**file = malloc(1 * sizeof(char *));
*file[i] = calloc(1, sizeof(char));

while ((lecture = readdir(rep))) {
printf("%s\n", lecture->d_name);
if((strcmp(lecture->d_name, ".")!=0) && (strcmp(lecture->d_name, "..")!=0)){
temp = calloc(strlen(lecture->d_name), sizeof(char));
temp = strdup(lecture->d_name);
realloc(**file, (i+1) * sizeof(char *));
realloc(*file[i], strlen(temp)* sizeof(char));
*file[i] = strdup(temp);
free(temp);
i = i + 1;
}
}
closedir(rep);

return i;
}


j'arrive à récupérer 2 valeurs puis j'obtiens un "segmentation fault" sur l'execution de la ligne " *file[i] = strdup(temp); " lors du chargement de la 3ème valeur. Peu importe le répertoire visé.

L'allocation est-elle correcte?
Messages postés
5
Date d'inscription
mercredi 26 novembre 2014
Statut
Membre
Dernière intervention
27 novembre 2014

Voici une version plus épurée:

int FileRepList(char ***file){
struct dirent *lecture;
DIR *rep;
int i = 0;

rep = opendir("..");

**file = malloc(50 * sizeof(char *));

while ((lecture = readdir(rep))) {
printf("%s\n", lecture->d_name);
if((strcmp(lecture->d_name, ".")!=0) && (strcmp(lecture->d_name, "..")!=0)){
*file[i] = (char*) malloc(strlen(lecture->d_name)* sizeof(char));
*file[i] = strdup(lecture->d_name);
i = i + 1;
}
}
closedir(rep);

return i;
}


je suis pratiquement sur que le soucis réside dans la ligne: " **file = malloc(50 * sizeof(char *)); " mais je n'arrive pas à déterminer pourquoi.

Auriez vous une idée?
Messages postés
5
Date d'inscription
mercredi 26 novembre 2014
Statut
Membre
Dernière intervention
27 novembre 2014

J'ai réussi à trouver une solution à mon problême. Voici mon programme:

int FileRepList(char **file){
struct dirent *lecture;
DIR *rep;
int i = 0;

rep = opendir(".");

while ((lecture = readdir(rep))) {
printf("%s\n", lecture->d_name);
if((strcmp(lecture->d_name, ".")!=0) && (strcmp(lecture->d_name, "..")!=0)){
file[i] = strdup(lecture->d_name);
i = i + 1;
}
}
closedir(rep);

return i;
}

int main()
{
char **file = NULL;
int nb = 0;
int i = 0;

file = (char**) malloc(50 * sizeof(char *));
nb = FileRepList(file);
realloc(file, nb * sizeof(char *));


for(i=0;i<nb;i++){
printf("\nfile[%d]: %s", i, file[i]);
}

free(file);

return 0;
}