C file explorer script

Asked

Viewed 307 times

-2

Good evening, everyone.

I need to implement a C program that works as a.s file explorer system. 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 listing of exploited directories and files, printing each level of exploration on the screen. Image-wise: inserir a descrição da imagem aqui

The data structure shall be arranged in the form of image-chained lists: inserir a descrição da imagem aqui

Each element of the structure must be composed by the name of the directory or file, a reference to its next file (if any) and, in the case of a directory, a reference to its first child, if any. Below is a suggestion for defining the element.

So far what I have is:

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

The Script must contain the excerpt listed above.

Thank you very much! The Script must be only in C.

  • Hi, @Vitorlucasbr92. What exactly is your question at the moment? Your question is very broad as it is.

  • In POSIX the usual way to read directories is with readdir(); in Windows you can use FindFirstFile(), FindNextFile(), and FindClose().

  • I’m going to do a test. @Pablo my doubt is about how to build this script because I’ve already broken my head a lot but I can’t get out of place. Could you help me?

  • Remembering that necessarily has to be in C, not C++

  • I don’t know who gave you that assignment, but it’s not a good one. As @pmg said, there is no portable way to do this in C. You’ll have to use preprocessor directives to differentiate between POSIX and Windows platforms at build time.

  • In reality it is a work of Faculty, but it is not easy to solve. And for this reason I have resorted so far.

  • I put down a piece of script. Can anyone help me??

Show 2 more comments

1 answer

0

Follow final code complete. 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");   
    }
}

Browser other questions tagged

You are not signed in. Login or sign up in order to post.