C file explorer script

-2

Good evening guys.

I need to implement a C program that works like a file explorer system .s. The program should allow you to explore computer locations by ADVANCING and RETURNING directories and dynamically creating a data structure in memory to store the directory listing and exploited files by printing each scan level on the screen. As picture:

Thedatastructureshouldbeorganizedasalinkedlistasshown:

Each element of the structure must consist of the name of the directory or file, a reference to its neighbor file (if any) and, in the case of a directory, a reference to its first child, if any. The following is a suggestion for setting the element.

So far what I have is:

typedef struct sElemento{   
char nome[100];    
struct sElemento *vizinho;   
struct sElemento *filho;  
} ELEMENTO; 

Script should contain the snippet listed above.

Thank you in advance! Script must be in C only.

    
asked by anonymous 11.11.2015 / 01:36

1 answer

0

Follow the final complete code. Credits: My teacher.

// Bibliotecas utilizadas
#include <stdio.h>;
#include <stdlib.h>
#include <string.h>
#include <dirent.h>

// Struct sugerida para representar cada elemento da estrutura de dados
typedef struct sElemento{
    char nome[100];
    struct sElemento *vizinho;
    struct sElemento *filho;
} ELEMENTO;

// Função que recebe uma referência do primeiro elemento da estrutura (C:\)
// e a tabulação para impressão identada dos diretórios e arquivos
void imprimir(ELEMENTO *p, char *tab){

    // Ponteiro auxiliar para percorrer o filho e vizinhos do elemento a ser impresso
    ELEMENTO *p_aux;

    // Variável para aumentar o tabulação a cada chamada recursiva da função
    char str[80];
    strcpy (str,tab);
    strcat (str,"  ");

    // Se o elemento tem filho, se tem subdiretórios
    if(p->filho){
        // Ponteiro auxiliar recebe o endereço do filho, primeiro elemento
        p_aux = p->filho;
        // Enquanto o elemento tiver um endereço de memória alocada, ou seja, for diferente de NULL
        while(p_aux){
            // Imprime a tabulação e o nome do elemento
            printf("%s%s\n", str, p_aux->nome);
            // Chamada recursiva para continuar imprimindo os filhos do elemento, se houver (APLICAÇÃO INTERESSANTE DE RECURSIVIDADE)
            imprimir(p_aux, str);
            // Ponteiro auxiliar recebe o endereço do viznho, para continuar imprimindo até que não haja mais vizinhos
            p_aux = p_aux->vizinho;
        }
    }
}

// Função que recebe uma referência do elemento a ser explorado
// e o nome do diretório completo (desde c:\...) para abertura do mesmo
// Retorna o primeiro diretório filho do diretório explorado
// para continuar como referência de elemento corrente na função main
ELEMENTO * avance(ELEMENTO *p, char* nome){

    // Ponteiro auxiliar para percorrer o filho e os vizinhos do elemento a ser explorado
    ELEMENTO *p_aux;
    // Variáveis para leitura dos diretórios e arquivos do windows
    DIR *p_dir;
    struct dirent *p_elemento; 
    // Contador para identificar o primeiro diretório ou arquivo do elemento a ser explorado, ou seja, o filho
    int first = 1;

    // Guarda o endereço do elemento a ser explorado em um ponteiro auxiliar que será utilizado para 
    // percorrer os demais sem perder a referência do elemento a ser explorado
    p_aux = p;

    // Abertura do diretório principal (C:\) e loop para percorrer todos os seus subdiretórios e arquivos
    p_dir = opendir(nome);
    while ( ( p_elemento = readdir(p_dir) ) != 0 ){

        // Se for o primeiro subdiretório ou arquivo, então aloca memória e guarda o endereço
        // de memória alocada no campo filho do elemento a ser explorado
        if(first){
            printf("%s\n", p_elemento->d_name);
            p_aux->filho = malloc(sizeof(ELEMENTO));
            // Atribui para o ponteiro auxiliar o endereço do elemento alocado
            p_aux = p_aux->filho;
            // Copia os valores para o elemento alocado
            strcpy(p_aux->nome, p_elemento->d_name);
            p_aux->vizinho = NULL;
            p_aux->filho = NULL;
            // Atribui zero para identificar que o primeiro elemento já foi alocado
            first = 0;
        }
        else{
            printf("%s\n", p_elemento->d_name);
            p_aux->vizinho = malloc(sizeof(ELEMENTO));
            p_aux = p_aux->vizinho;
            // Copia os valores para o elemento alocado
            strcpy(p_aux->nome, p_elemento->d_name);
            p_aux->vizinho = NULL;
            p_aux->filho = NULL;
        }
    }
    // Fechar o diretório explorado
    closedir(p_dir);

    // Retorno o primeiro diretório, ou seja, o filho do diretório explorado,
    // para continuar como referência de elemento corrente na função main
    return p->filho;
}

int main(){

    // Ponteiro para o primeiro elemento e ponteiros auxiliares para percorrer filhos e vizinhos
    ELEMENTO *p, *p_aux, *p_aux_first;
    // Variáveis para leitura dos diretórios e arquivos do windows
    DIR *p_dir;
    struct dirent *p_elemento;
    // Contador para identificar o primeiro diretório ou arquivo, ou seja, o filho
    int first = 1;
    // Variáveis para armazenar o comando digitado pelo usuário e o nome do diretório a ser avançado
    char comando[100], nome[100];

    // Mensagens para o usuário
    puts("Sistema Explorador de Arquivos [versao 1.0]");
    puts("\n");
    puts("EXPLORANDO C:\");
    puts("\n");

    // Alocação de memória para o primeiro elemento (C:\)
    p = malloc(sizeof(ELEMENTO));
    strcpy(p->nome, "C:\");
    p->vizinho = NULL;
    p->filho = NULL;

    // Guarda o endereço do primeiro elemento em um ponteiro auxiliar que será utilizado para 
    // percorrer os demais sem perder a referência do início da estrutura de dados
    p_aux = p;

    // Abertura do diretório principal (C:\) e loop para percorrer todos os seus subdiretórios e arquivos
    p_dir = opendir(p->nome);
    while ( ( p_elemento = readdir(p_dir) ) != 0 ){

        // Se for o primeiro subdiretório ou arquivo, então aloca memória e guarda o endereço
        // de memória alocada no campo filho do elemento principal (C:\)
        if(first){
            printf("%s\n", p_elemento->d_name);
            p_aux->filho = malloc(sizeof(ELEMENTO));
            // Atribui para o ponteiro auxiliar o endereço do elemento alocado
            p_aux = p_aux->filho;
            // Copia os valores para o elemento alocado
            strcpy(p_aux->nome, p_elemento->d_name);
            p_aux->vizinho = NULL;
            p_aux->filho = NULL;
            // Atribui zero para identificar que o primeiro elemento já foi alocado
            first = 0;
        }
        // Senão, aloca memória e guarda o endereço de memória alocada para o vizinho do elemento corrente
        else{
            printf("%s\n", p_elemento->d_name);
            p_aux->vizinho = malloc(sizeof(ELEMENTO));
            // Atribui para o ponteiro auxiliar o endereço do elemento alocado
            p_aux = p_aux->vizinho;
            // Copia os valores para o elemento alocado
            strcpy(p_aux->nome, p_elemento->d_name);
            p_aux->vizinho = NULL;
            p_aux->filho = NULL;
        }
    }
    // Fechar o diretório explorado
    closedir(p_dir);

    // Guarda no ponteiro auxiliar o endereço do primeiro elemento, filho do elemento principal (C:\)
    p_aux = p->filho;

    // Loop infinito
    for(;;){

        // Opções do usuário
        puts("\n");
        puts("AVANCAR ou IMPRIMIR");
        scanf("%s", comando);

        // Se a opção digitada for IMPRIMIR, então imprime o nome do elemento principal (C:\) chama a função de impressão
        if(stricmp(comando, "IMPRIMIR") == 0){
            puts("\n");
            puts("IMPRIMINDO ESTRUTURA DE DADOS CRIADA ...");
            puts("\n");
            printf("%s\n", p->nome);
            imprimir(p, "");
            // Sai do loop infinito e encerra o programa
            break;
        }
        else
        // Se a opção digitada for AVANCAR, então solicita ao usuário o caminho a ser avançado
        if(stricmp(comando, "AVANCAR") == 0){

            puts("Entre com o caminho (ex. C:\Windows): ");
            scanf(" %[^\n]s", nome);

            // Guarda o endereço do primeiro elemento do diretório corrente para caso não encontrar o diretório digitado
            p_aux_first = p_aux;

            // Enquando o ponteiro auxiliar guardar um endereço de memória alocada, ou seja, não for NULL
            while(p_aux){

                // Testa se o nome do elemento corrente está contido no endereço digitado, a partir da última barra
                if(stricmp(p_aux->nome, strrchr(nome, '\') + 1) == 0){
                    puts("\n");
                    printf("EXPLORANDO %s", nome);
                    puts("\n");
                    // Chama função para avançar, que faz seu trabalho e retorna o primeiro elemento do diretório avançado
                    p_aux = avance(p_aux, nome);
                    // Quebra o loop, sai do while
                    break;
                }
                // Atualiza o ponteiro auxiliar para que o elemento corrente agora seja o seu vizinho
                p_aux = p_aux->vizinho;
            }
            // Se percorreu todos os vizinhos e não encontrou o diretório
            if(p_aux==NULL){
                puts("Diretorio Invalido");
                // Volta para o ponteiro auxiliar o endereço do primeiro elemento do diretório corrente
                p_aux = p_aux_first;
            }
        }

        else
            puts("Comando Invalido");   
    }
}
    
16.11.2015 / 12:05