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.
A voir également:

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