Ir para conteúdo
Fórum Script Brasil
  • 0

(Resolvido) Problema desconhecido


RootUser

Pergunta

Não sei o porque, mas este código não imprime o nome dos diretórios e arquivos, e também não fecha o diretório aberto...

#include<stddef.h>
#include<stdio.h>
#include<sys/types.h>
#include<dirent.h>

void get_files(char *dir, char **content, int *i)
{
    DIR *dp;
    struct dirent *ep;
    dp = opendir(dir);
    
    if(!dp)
    {
        printf("Error!!!\n");
        exit(-1);
    }
    else
    {
        while(ep = readdir(dp)) 
        {
            content = malloc((*i+1) * sizeof(char *));
            content[*i] = calloc(strlen(ep->d_name),sizeof(char));
            
            if(strcmp(ep->d_name,".") != 0 && strcmp(ep->d_name,".."))
            {
                strcpy(content[*i],ep->d_name);
                strcat(content[*i],"");
                *i = *i + 1;
            }
        }
        if(!closedir(dp))
        {
            printf("Can't close the dir.\n");
        }
    }
}

int main()
{
    int i=0,j;
    char **files;
    get_files(".",files,&i);
    
    for(j=0; j<i; j++) printf("%s\n", files[j]);
    
    return 0;
}

Alguém poderia me ajudar?

Desde já agradeço.

Ass.: RootUser

Link para o comentário
Compartilhar em outros sites

5 respostass a esta questão

Posts Recomendados

  • 0

Bom dia!

Um dos problemas está com esse malloc, ele não está fazendo o que você queria que ele fizesse:

content = malloc((*i+1) * sizeof(char *));
Ele NÃO mantém a refêrencia para a memória antiga. Veja o exemplo:
#include <stdio.h>
#include <stdlib.h>
int main( int argc , char **argv ){
    
    int *teste;
    int i;

    //Adicionando o segundo elemento
    teste = (int *) malloc( 1 * sizeof( int ) );
    teste[0] = 10;

    //Adicionando o segundo elemento    
    teste = (int *) malloc( 2 * sizeof( int ) );
    teste[1] = 20;

    //Adicionando o terceiro elemento    
    teste = (int *) malloc( 3 * sizeof( int ) );
    teste[2] = 30;

    //Mostrando o resultado
    for( i = 0; i < 3; i++ ){
        printf( "%d\n" , teste[i] );
    }
}
/*
Resultado obtido:
0
0
30

Resultado esperado:
10
20
30
*/
Sugiro que você dê uma olhada em realloc[http://www.cplusplus.com/reference/clibrary/cstdlib/realloc/]. Outro problema está aqui:
if(!closedir(dp))
        {
            printf("Can't close the dir.\n");
        }
Olhando a descrição da função:
CLOSEDIR

NAME
       closedir - close a directory

SYNOPSIS
       #include <sys/types.h>
       #include <dirent.h>
       int closedir(DIR *dir);

DESCRIPTION
       The  closedir() function closes the directory stream asso-
       ciated with dir.  The directory stream descriptor  dir  is
       not available after this call.

RETURN VALUE
       The  closedir()  function  returns  0  on success or -1 on
       failure.
Então quando o diretório for fechado corretamente, irá retornar 0 (que é interpretado como false), como você faz a condição de negação (!closedir()), quando o closedir retornar 0 (o diretório foi fechado CORRETAMENTE), a expressão (!closedir()) vai ser interpretada como true, o que não é verdade! Para esclarecer:
#include <stdio.h>

int main( int argc , char **argv ){
    if( !(0) ){//Close dir retornou 0, diretório fechado corretamente
        printf( "0 é considerado TRUE" );
    }
    if( !(-1) ){//Close dir retornou -1, diretório fechado INcorretamente
        printf( "-1 é considerado TRUE" );
    }
}
/*
Resultado:
0 é considerado TRUE

Editado por p4t0X
Link para o comentário
Compartilhar em outros sites

  • 0

Obrigado pela resosta p4t0X, estou verificando todas as suas sugestões, mas não entedi a seguinte sugestão:

Outro problema está aqui:

if(!closedir(dp))
        {
            printf("Can't close the dir.\n");
        }
Olhando a descrição da função:
CLOSEDIR

NAME
       closedir - close a directory

SYNOPSIS
       #include <sys/types.h>
       #include <dirent.h>
       int closedir(DIR *dir);

DESCRIPTION
       The  closedir() function closes the directory stream asso-
       ciated with dir.  The directory stream descriptor  dir  is
       not available after this call.

RETURN VALUE
       The  closedir()  function  returns  0  on success or -1 on
       failure.
Então quando o diretório for fechado corretamente, irá retornar 0 (que é interpretado como false), como você faz a condição de negação (!closedir()), quando o closedir retornar 0 (o diretório foi fechado CORRETAMENTE), a expressão (!closedir()) vai ser interpretada como true, o que não é verdade! Para esclarecer:
#include <stdio.h>

int main( int argc , char **argv ){
    if( !(0) ){//Close dir retornou 0, diretório fechado corretamente
        printf( "0 é considerado TRUE" );
    }
    if( !(-1) ){//Close dir retornou -1, diretório fechado INcorretamente
        printf( "-1 é considerado TRUE" );
    }
}
/*
Resultado:
0 é considerado TRUE
Isso não faria com que o meu programa imprimisse a mensagem de erro "Can't close the dir. " ("Não é possivel fechar o diretório") quando o diretório fosse corretamente fechado? Eu fiz esse código baseado nesse, vou postá-lo abaixo no caso de ele ser utíl.
#include <errno.h> 
#include <dirent.h> 
#include <stdio.h> 
#include <stdlib.h> 

int main() 
{
 DIR *pdir;
 struct dirent *pent;

 pdir=opendir("."); //"." refers to the current dir
 if (!pdir){
  printf ("opendir() failure; terminating");
  exit(1);
 }
 errno=0; 
 while ((pent=readdir(pdir))){
   printf("%s\n", pent->d_name);
 }
 if (errno){
  printf ("readdir() failure; terminating");
  exit(1);
 }
 closedir(pdir);
}

Em todo o caso obrigado pela ajuda p4t0X.

Link para o comentário
Compartilhar em outros sites

  • 0

Opa, boa noite!

Então, a principal razão dele não estar funcionando foi o treco do malloc alí...

A questão do closedir eu só falei por falar, embora no caso realmente não esteja resultando em nada ;)

btw, tá aí oh:

#include<stdlib.h>
#include<stdio.h>
#include<sys/types.h>
#include<dirent.h>
#include<string.h>

void get_files(char *dir, char **content, int *i){
    DIR *dp;
    struct dirent *ep;
    dp = opendir(dir);    

    if( !dp ){
        printf("Error!!!\n");
        exit(-1);
    }else{
        while( NULL != ( ep = readdir(dp) ) ){
            //Realoca a memória existente adicionando +1 posição
            content = (char **) realloc( content, (*i+1) * sizeof(char *) );
            if( content == NULL ){
                printf( "Erro no realloc!" );
                exit( -1 );
            }
            
            //Aloca a quantidade necessária para o nome do arquivo atual
            content[*i] = (char *) malloc( ( strlen( ep->d_name ) ) * sizeof(char) );   
            if( content[*i] == NULL ){
                printf( "Putz, impossivel alocar mais memoria!" );
                exit( -1 );
            }
            
            //Copia a string
            strcpy(content[*i],ep->d_name);
            
            //Incrementa o número de arquivos
            *i = *i + 1;
        }
        if( closedir( dp ) ){
            printf("Can't close the dir.\n");
        }
    }
}


int main( int argc, char **argv ){
    int i=0,j;
    char **files;
    get_files(".",files,&i);
    
    for( j = 0; j < i; j++ ){
        printf ("%s\n" , files[j] );
    }

    return 0;
}

Qualquer coisa dá um toque! Até se funcionar...

PS: Testei aqui no trampo não rodou, aqui eu uso Ubuntu e compilo com gcc, porém em casa tinha funcionado (DevCpp com mingw (acho)

[]'s

Editado por p4t0X
Link para o comentário
Compartilhar em outros sites

  • 0

Bom dia!

Dando uma estudada melhor no código eu acho que eu descobri o erro!

A variável files está sendo passada por VALOR.

Tem 2 soluções:

1) A função retornar um ponteiro;

2) Passar a variavel por referencia;

Aqui eu adptei rapidamente para a 2 opção:

#include<stdlib.h>
#include<stdio.h>
#include<sys/types.h>
#include<dirent.h>
#include<string.h>

void get_files(char *dir, char ***content, int *i){
    DIR *dp;
    struct dirent *ep;
    dp = opendir(dir);    

    if( !dp ){
        printf("Error!!!\n");
        exit(-1);
    }else{
        while( NULL != ( ep = readdir(dp) ) ){

        
                //Realoca a memória existente adicionando +1 posição
                (*content) = (char **) realloc( (*content), (*i+1) * sizeof(char *) );
            
            if( (*content) == NULL ){
                printf( "Erro no realloc!" );
                exit( -1 );
            }
            
            //Aloca a quantidade necessária para o nome do arquivo atual
            (*content)[*i] = (char *) malloc( ( strlen( ep->d_name ) ) * sizeof(char) );   
            if( (*content)[*i] == NULL ){
                printf( "Putz, impossivel alocar mais memoria!" );
                exit( -1 );
            }
            
            //Copia a string
            strcpy((*content)[*i],ep->d_name);
            
            //Incrementa o número de arquivos
            *i = *i + 1;
        }
        if( closedir( dp ) ){
            printf("Can't close the dir.\n");
        }
    }
}


int main( int argc, char **argv ){
    int i=0,j;
    char **files = (char **) malloc( sizeof( char *) );
    get_files(".",&files,&i);
    for( j = 0; j < i; j++ ){
        printf ("%s\n" , files[j] );
    }

    return 0;
}

Testei no ubuntu e no windows, tudo normal!

[]'s

Link para o comentário
Compartilhar em outros sites

  • 0

Muito obrigado pela ajuda p4t0X, o código está funcionando perfeitamente agora, só mudei a linha 40 para "if( closedir( dp ) == -1 )".

#include<stdlib.h>
#include<stdio.h>
#include<sys/types.h>
#include<dirent.h>
#include<string.h>

void get_files(char *dir, char ***content, int *i){
    DIR *dp;
    struct dirent *ep;
    dp = opendir(dir);    

    if( !dp ){
        printf("Error!!!\n");
        exit(-1);
    }else{
        while( NULL != ( ep = readdir(dp) ) ){

        
                //Realoca a memória existente adicionando +1 posição
                (*content) = (char **) realloc( (*content), (*i+1) * sizeof(char *) );
            
            if( (*content) == NULL ){
                printf( "Erro no realloc!" );
                exit( -1 );
            }
            
            //Aloca a quantidade necessária para o nome do arquivo atual
            (*content)[*i] = (char *) malloc( ( strlen( ep->d_name ) ) * sizeof(char) );  
            if( (*content)[*i] == NULL ){
                printf( "No memory...\n" );
                exit( -1 );
            }
            
            //Copia a string
            strcpy((*content)[*i],ep->d_name);
            
            //Incrementa o número de arquivos
            *i = *i + 1;
        }
        if( closedir( dp ) == -1 ){
            printf("Can't close the dir.\n");
        }
    }
}


int main( int argc, char **argv ){
    int i=0,j;
    char **files = (char **) malloc( sizeof( char *) );
    get_files(".",&files,&i);
    for( j = 0; j < i; j++ ){
        printf ("%s\n" , files[j] );
    }

    return 0;
}

PS.: Código testado no Slackware 13.

Link para o comentário
Compartilhar em outros sites

Participe da discussão

Você pode postar agora e se registrar depois. Se você já tem uma conta, acesse agora para postar com sua conta.

Visitante
Responder esta pergunta...

×   Você colou conteúdo com formatação.   Remover formatação

  Apenas 75 emoticons são permitidos.

×   Seu link foi incorporado automaticamente.   Exibir como um link em vez disso

×   Seu conteúdo anterior foi restaurado.   Limpar Editor

×   Você não pode colar imagens diretamente. Carregar ou inserir imagens do URL.



  • Estatísticas dos Fóruns

    • Tópicos
      152,3k
    • Posts
      652,4k
×
×
  • Criar Novo...