Récupération d'un tableau de chaines de caractères

Résolu/Fermé
scaul
Messages postés
5
Date d'inscription
mercredi 26 novembre 2014
Statut
Membre
Dernière intervention
27 novembre 2014
- Modifié par scaul le 26/11/2014 à 14:19
scaul
Messages postés
5
Date d'inscription
mercredi 26 novembre 2014
Statut
Membre
Dernière intervention
27 novembre 2014
- 27 nov. 2014 à 18:41
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

productif
Messages postés
39
Date d'inscription
mardi 8 mars 2011
Statut
Membre
Dernière intervention
9 février 2017
20
26 nov. 2014 à 23:55
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...
0
scaul
Messages postés
5
Date d'inscription
mercredi 26 novembre 2014
Statut
Membre
Dernière intervention
27 novembre 2014

Modifié par scaul le 27/11/2014 à 12:05
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?
0
scaul
Messages postés
5
Date d'inscription
mercredi 26 novembre 2014
Statut
Membre
Dernière intervention
27 novembre 2014

27 nov. 2014 à 16:46
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?
0
scaul
Messages postés
5
Date d'inscription
mercredi 26 novembre 2014
Statut
Membre
Dernière intervention
27 novembre 2014

27 nov. 2014 à 18:41
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;
}
0