Как вывести список файлов в каталоге, который находится в каталоге в C? - PullRequest
1 голос
/ 29 сентября 2019

Я пытаюсь перечислить файлы в каталоге до определенного уровня, который указан пользователем.

Основная проблема, с которой я сталкиваюсь, заключается в том, что я считаю, что подкаталоги не распознаютсяв качестве каталога. Поэтому я попытался добавить строку на верхний уровень каталога. Но, похоже, он не работает.

Вот структура каталогов, сгенерированная с помощью ls -R (Все каталоги dir * являются каталогами):

dir1  dir2  dir3  listDirectory  listDirectory.c

./dir1:
dir1.1  dir1.2  dir1.3

./dir1/dir1.1:
dir1.1.1

./dir1/dir1.1/dir1.1.1:

./dir1/dir1.2:

./dir1/dir1.3:

./dir2:
dir2.1  dir2.2  dir2.3

./dir2/dir2.1:

./dir2/dir2.2:

./dir2/dir2.3:

./dir3:

Вот код:

#include <stdio.h>
#include <dirent.h>
#include <string.h>

#include <regex.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>

struct stat s;

regex_t regex;
const char *expression = "^[.]*$";
int reti;


//Directory listing main loop

int listDirectory(int counter,int level,char arr[200]){
    printf("Here Counter = %d and Level = %d\n", counter, level);

    //Check if the counter is equal to level. If yes exit
    if(counter >= level){
        return 0;
    }

    char *currentDirctory = arr;
    // printf("%s\n",currentDirctory);

    struct dirent *de;                   // Pointer for directory entry 
    DIR *dr = opendir(currentDirctory);  // opendir() returns a pointer of DIR type.  
    if (dr == NULL)                      // opendir returns NULL if couldn't open directory 
    {
        printf("Could not open current directory");
        return 0;
    }

    //Read the contents of the directory
    while ((de = readdir(dr)) != NULL){
        int size = 0;

        struct stat statbuf;

        char *x = de->d_name; //The name of each file or folder
        char c2[100];
        strcpy(c2,x);
        strcpy(arr,c2);
        //Replace the content of arr with that of new directory or file name
        reti = regexec(&regex, arr, 0, NULL, 0);
        //Check if the file doesn't match . or .. which is the parent and grand-parent directory
        if(!reti){
            //If it matches check for next file
            continue;
        }
        else if(reti == REG_NOMATCH){
            printf("%s\n",arr);
            //Check if the file or the path is a direcfory
            stat(arr, &statbuf);
            if(S_ISDIR(statbuf.st_mode)){
                //If it is a directory then increase the counter and size and put the directory in loop for next call
                counter += 1;
                listDirectory(counter,level, arr);
                size += 1;
            }
            else{
                //It is a file check for next file
                continue;
            }
            counter -= size;

        }
    }
    closedir(dr);
}

int main(){
    char arr[200] = "./";
    reti = regcomp(&regex, expression, 0);
    if(reti) {
        fprintf(stderr, "Could not compile regex\n");
    }
    listDirectory(0,2,arr);
    return 0; 
}

Вывод:

Here Counter = 0 and Level = 2
dir3
Here Counter = 1 and Level = 2
listDirectory.c
dir1
Here Counter = 1 and Level = 2
dir1.1
dir1.3
dir1.2
listDirectory
dir2
Here Counter = 1 and Level = 2
dir2.3
dir2.2
dir2.1

, но должен быть:

Here Counter = 0 and Level = 2
dir3
Here Counter = 1 and Level = 2
listDirectory.c
dir1
Here Counter = 1 and Level = 2
dir1.1
Here Counter = 2 and Level = 2
dir1.1.1
dir1.2
listDirectory
dir2
Here Counter = 1 and Level = 2
dir2.3
dir2.2
dir2.1

1 Ответ

0 голосов
/ 30 сентября 2019

Наконец-то это сработало. Я сделал много изменений, поэтому не знаю, какая линия работала. Итак, вот результирующий код

#include <stdio.h>
#include <dirent.h>
#include <string.h>
#include <stdlib.h>

#include <regex.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>

struct stat s;

regex_t regex;
const char *expression = "^[.]*$";
int reti;


//Directory listing main loop

int listDirectory(int counter,int level,char arr[200]){
    printf("Here Counter = %d and Level = %d and directory is %s\n", counter, level, arr);

    char c = '/';

    size_t len = strlen(arr);
    char *str2 = malloc(len + 1 + 1 );
    strcpy(str2, arr);

    str2[len] = c;
    str2[len + 1] = '\0';

    //Check if the counter is equal to level. If yes exit
    if(counter >= level){
        return 0;
    }

    char *currentDirctory = str2;
    // printf("%s\n",currentDirctory);

    struct dirent *de;                   // Pointer for directory entry 
    DIR *dr = opendir(currentDirctory);  // opendir() returns a pointer of DIR type.  
    if (dr == NULL)                      // opendir returns NULL if couldn't open directory 
    {
        // printf("\nCould not open current directory\n");
        return 0;
    }

    char root[100];
    strcpy(root,str2);

    //Read the contents of the directory
    while ((de = readdir(dr)) != NULL){
        int size = 0;

        struct stat statbuf;

        char *x = de->d_name; //The name of each file or folder
        char c2[100];

        strcpy(c2,x);

        strcpy(currentDirctory,c2);

        //Replace the content of arr with that of new directory or file name
        reti = regexec(&regex, currentDirctory, 0, NULL, 0);
        //Check if the file doesn't match . or .. which is the parent and grand-parent directory
        if(!reti){
            //If it matches check for next file
            continue;
        }
        else if(reti == REG_NOMATCH){
            //Check if the file or the path is a direcfory
            // printf("\nRoot is %s\n",str2);
            stat(arr, &statbuf);
            // if(S_ISDIR(statbuf.st_mode)){
                //If it is a directory then increase the counter and size and put the directory in loop for next call
                // printf("%s %s\n",arr,str2);
                counter += 1;

                size_t len = strlen(root);
                size_t len2 = strlen(currentDirctory);

                char *str3 = malloc(len + len2 + 1 );

                strcpy(str3, root);
                strcat(str3,currentDirctory);
                // str3[len] = currentDirctory;
                str3[len2 + len + 1] = '\0';

                // printf("\nGoing into loop directory is %s root is %s\n",str3,root);
                listDirectory(counter,level, str3);
                size += 1;
            // }
            // else{
                //It is a file check for next file
                // continue;
            // }
            counter -= size;

        }
    }
    closedir(dr);
}

int main(){
    char arr[200] = ".";
    reti = regcomp(&regex, expression, 0);
    if(reti) {
        fprintf(stderr, "Could not compile regex\n");
    }
    listDirectory(0,3,arr);
    return 0; 
}

...