如何列出C中某个目录下的目录中的文件?

时间:2019-09-29 20:28:42

标签: c pointers recursion directory file-handling

我正在尝试将目录中的文件列出到用户指定的特定级别。

我面临的主要问题是我认为子目录不被识别为目录。因此,我尝试将字符串追加到目录的上级。但这似乎不起作用。

这是使用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 :(得分:0)

最后它成功了。 我做了很多更改,所以不知道哪条线有效。 这是结果代码

#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; 
}