Ir ao conteúdo
  • Cadastre-se

Listar arquivos de um diretório.


Ir à solução Resolvido por dontpanic,

Posts recomendados

Galera,tô tentando fazer um programa que remove arquivos repetidos de uma pasta. Tô bem no comecinho e tô com um problema besta :

 

Consegui listar arquivos de um diretório, vi uns artigos sobre dirent.h e consegui fazer isso.Mas agora não tô conseguindo passar os nomes dos arquivos das pastas pra uma matriz de caracteres.Quando tento salvar todas as posições da minha matriz ficam com o nome do última pasta. Tenho aqui o código que tenho até agora.

Obrigado desde já.

#include <stdio.h>#include <stdlib.h>#include <string.h>#include <dirent.h>int main(){        char dirn[50];        char **mat;        int i = 0;        DIR *dir = NULL;        struct dirent *drnt = NULL;        mat =(char**)malloc(sizeof(char*)*20);        for(i=0;i<20;i++){                    mat[i] =(char*)malloc(sizeof(char)*20);        }        printf("Caminho da pasta: ");        gets(dirn);        dir=opendir(dirn);        if(dir)        {                printf("Saída:\n");                while(drnt = readdir(dir))                {                        //printf("%-20s\n", drnt->d_name);                        mat[i] = drnt->d_name;                        i++;                }                closedir(dir);        }        else        {                printf("Não foi possível abrir essa pasta '%s'\n", dirn);        }        for (i=0;i<50;i++){            printf("%s",mat[i]);        }        return 0;}
Link para o comentário
Compartilhar em outros sites

  • Solução

Quando você chama a função openDir(), ela pega a lista dos arquivos no diretório e coloca tudo numa lista interna de estruturas.

Depois ao chamar a função readdir(), ela percorre essa lista, item por item, e devolve o endereço desses items da lista.

dir=opendir(dirn); // criou a lista de arquivos do diretório aqui...while(drnt = readdir(dir)) // percorrendo a lista aqui
 

Até aí tudo bem, certo?

Depois disso você usou teu array de ponteiros pra pegar o endereço das strings que guardam o nome desses arquivos no diretório:

mat[i] = drnt->d_name;
 

Até aí tudo certo também. Essa operação por si só não é incorreta.

O problema é que fazendo isso, seu array de ponteiros acabou de jogar fora todos aqueles endereços que você tinha reservado lá em cima com o malloc:

for (i=0;i<20;i++){    mat[i] = (char*) malloc(sizeof(char)*20);}
 

E o problema maior ainda, é que os endereços novos que seu array de ponteiros está guardando, são endereços gerenciados pelo próprio <dirent.h>.

Ou seja, quando você chamar a função closeDir(), ou mesmo quando o readDir() chegar no final da lista, esses endereços serão liberados e o seu array de ponteiros estará apontando para endereços desalocados na memória.

 

Se você quer guardar no seu array de ponteiros os nomes dos arquivos do diretório, então em vez de pegar o endereço deles, você precisa pegar o CONTEÚDO deles.

Pra isso você usa a função strcpy:

while( (drnt = readdir(dir)) ){    strcpy(mat[i], drnt->d_name);    i++;}
 

No entanto, tem outro erro que você deixou passar, que é o motivo principal do seu código estar travando:

for(i=0;i<20;i++){    mat[i] =(char*)malloc(sizeof(char)*20);} // NESSE PONTO DO CÓDIGO, i É IGUAL A 20. ...while(drnt = readdir(dir)){    mat[i] = drnt->d_name; // QUANDO CHEGAR AQUI, [i] VAI SER 20, EM VEZ DE 0.    i++; // 21, 22, 23...}
 

Você esqueceu de resetar o i.

E por fim, você tá tentando imprimir os 50 items do seu array, quando na verdade você só reservou 20:

 

for (i=0;i<50;i++){ ... }
Edit:

Ah! Já ia esquecendo:

for(i=0;i<20;i++){    free(mat[i]);}free(mat);
Pra economizar 1.6kb de ram :P
  • Curtir 1
Link para o comentário
Compartilhar em outros sites

Quando você chama a função openDir(), ela pega a lista dos arquivos no diretório e coloca tudo numa lista interna de estruturas.

Depois ao chamar a função readdir(), ela percorre essa lista, item por item, e devolve o endereço desses items da lista.

dir=opendir(dirn); // criou a lista de arquivos do diretório aqui...while(drnt = readdir(dir)) // percorrendo a lista aqui
 

Até aí tudo bem, certo?

Depois disso você usou teu array de ponteiros pra pegar o endereço das strings que guardam o nome desses arquivos no diretório:

mat[i] = drnt->d_name;
 

Até aí tudo certo também. Essa operação por si só não é incorreta.

O problema é que fazendo isso, seu array de ponteiros acabou de jogar fora todos aqueles endereços que você tinha reservado lá em cima com o malloc:

for (i=0;i<20;i++){    mat[i] = (char*) malloc(sizeof(char)*20);}
 

E o problema maior ainda, é que os endereços novos que seu array de ponteiros está guardando, são endereços gerenciados pelo próprio <dirent.h>.

Ou seja, quando você chamar a função closeDir(), ou mesmo quando o readDir() chegar no final da lista, esses endereços serão liberados e o seu array de ponteiros estará apontando para endereços desalocados na memória.

 

Se você quer guardar no seu array de ponteiros os nomes dos arquivos do diretório, então em vez de pegar o endereço deles, você precisa pegar o CONTEÚDO deles.

Pra isso você usa a função strcpy:

while( (drnt = readdir(dir)) ){    strcpy(mat[i], drnt->d_name);    i++;}
 

No entanto, tem outro erro que você deixou passar, que é o motivo principal do seu código estar travando:

for(i=0;i<20;i++){    mat[i] =(char*)malloc(sizeof(char)*20);} // NESSE PONTO DO CÓDIGO, i É IGUAL A 20. ...while(drnt = readdir(dir)){    mat[i] = drnt->d_name; // QUANDO CHEGAR AQUI, [i] VAI SER 20, EM VEZ DE 0.    i++; // 21, 22, 23...}
 

Você esqueceu de resetar o i.

E por fim, você tá tentando imprimir os 50 items do seu array, quando na verdade você só reservou 20:

for (i=0;i<50;i++){ ... }

Simplesmente perfeito! Muito obrigado,cara! Ajudou bastante!

  • Curtir 1
Link para o comentário
Compartilhar em outros sites

Visitante
Este tópico está impedido de receber novas respostas.

Sobre o Clube do Hardware

No ar desde 1996, o Clube do Hardware é uma das maiores, mais antigas e mais respeitadas comunidades sobre tecnologia do Brasil. Leia mais

Direitos autorais

Não permitimos a cópia ou reprodução do conteúdo do nosso site, fórum, newsletters e redes sociais, mesmo citando-se a fonte. Leia mais

×
×
  • Criar novo...