Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/linux/27.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 如何递归列出所有目录?_C_Linux - Fatal编程技术网

C 如何递归列出所有目录?

C 如何递归列出所有目录?,c,linux,C,Linux,我的代码不起作用。我需要显示作为命令行参数给定的目录中的所有目录。到目前为止,我已经尝试过: #include <stdio.h> #include <dirent.h> #include <sys/stat.h> #include <sys/types.h> #include <stdlib.h> #include <unistd.h> struct stat my_stat; int searchDirectory

我的代码不起作用。我需要显示作为命令行参数给定的目录中的所有目录。到目前为止,我已经尝试过:

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

struct stat my_stat;

int searchDirectory (char *dirName);

int searchDirectory(char *dirName){
    struct dirent *pDirent;
    DIR *pDir;

    pDir = opendir(dirName);
    if (pDir == NULL) {
        printf("Cannot open directory '%s'\n", dirName );
        return 1;
    }

    while ((pDirent = readdir(pDir)) != NULL){
        printf("%s\n", pDirent->d_name);
        stat(pDirent->d_name, &my_stat);
        if (S_ISDIR(my_stat.st_mode)){
            searchDirectory(pDirent->d_name);
            printf("Directory Found: %s\n", pDirent->d_name);
        }
    }

    return 0;
}

int main(int argc, char *argv[]){
    struct stat my_stat;


    if (lstat(argv[1], &my_stat) < 0){
        perror("stat error");
    }

    if (S_ISDIR(my_stat.st_mode)){ 
        printf("Directory found\n");
        searchDirectory(argv[1]);
    }

    return 0;
}
#包括
#包括
#包括
#包括
#包括
#包括
struct stat my_stat;
int searchDirectory(char*dirName);
int searchDirectory(char*dirName){
结构方向*pDirect;
DIR*pDir;
pDir=opendir(dirName);
如果(pDir==NULL){
printf(“无法打开目录“%s”\n”,dirName);
返回1;
}
而((pDirent=readdir(pDir))!=NULL){
printf(“%s\n”,pDirent->d_name);
状态(pDirent->d_name和my_stat);
if(S_ISDIR(我的统计st_模式)){
搜索目录(pDirent->d_名称);
printf(“找到的目录:%s\n”,pDirent->d_name);
}
}
返回0;
}
int main(int argc,char*argv[]){
struct stat my_stat;
if(lstat(argv[1],&my_stat)<0){
perror(“统计错误”);
}
如果(S_ISDIR(my_stat.st_mode)){
printf(“找到目录\n”);
searchDirectory(argv[1]);
}
返回0;
}

我不知道为什么,但出于某种原因,我的代码正在将普通文件作为目录读取,但S_ISDIR(my_stat.st_mode))应该可以防止这种情况发生。有什么问题吗?

您遇到的问题是,
pDirent->d_name
与您当前列出的目录相关,而您的进程有一个启动进程的工作目录

要修复此问题,请在执行opendir之前先指定目录的名称

int searchDirectory(char *dirName){
    ......
    while ((pDirent = readdir(pDir)) != NULL){
        printf("%s\n", pDirent->d_name);
        stat(pDirent->d_name, &my_stat);
        if (S_ISDIR(my_stat.st_mode)){
            // construct new path ....
            char * dirname = malloc(strlen(dirName)+strlen(pDirent->d_name)+2);
            strcat(strcat(strcpy(dirname,dirName),"/"),pDirent->d_name);
            searchDirectory(dirname);
            free(dirname)
            printf("Directory Found: %s\n", pDirent->d_name);
        }
     }
     .....

另外请注意,您需要将
目录作为特殊情况处理,否则代码将以无限递归结束,因此,您需要额外的代码来处理这些问题——有关详细信息,请参见。您遇到的问题是,
pDirent->d_name
与当前列出的目录相关,而您的进程有一个启动进程的工作目录

要修复此问题,请在执行opendir之前先指定目录的名称

int searchDirectory(char *dirName){
    ......
    while ((pDirent = readdir(pDir)) != NULL){
        printf("%s\n", pDirent->d_name);
        stat(pDirent->d_name, &my_stat);
        if (S_ISDIR(my_stat.st_mode)){
            // construct new path ....
            char * dirname = malloc(strlen(dirName)+strlen(pDirent->d_name)+2);
            strcat(strcat(strcpy(dirname,dirName),"/"),pDirent->d_name);
            searchDirectory(dirname);
            free(dirname)
            printf("Directory Found: %s\n", pDirent->d_name);
        }
     }
     .....

还要注意的是,您需要将
目录作为特殊情况处理,否则代码将以无限递归结束,因此您需要额外的代码来处理这些目录——有关详细信息,请参阅对
搜索目录(pDirent->d_name)的递归调用
是错误的,因为您得到了一个相对于正在解析的目录的名称,所以您需要将实际解析的目录的名称和(相对于该目录的)相对名称连接起来:

char newDir[PATH_MAX];
snprintf(newDir,PATH_MAX,"%s/%s",dirName,pDirent->d_name);
searchDirectory(newDir);

递归调用
searchDirectory(pDirent->d_name)
是错误的,因为您得到了一个相对于正在解析的目录的名称,所以您需要将实际解析的目录的名称和(相对于该目录的)相对名称连接起来:

char newDir[PATH_MAX];
snprintf(newDir,PATH_MAX,"%s/%s",dirName,pDirent->d_name);
searchDirectory(newDir);

你的产出是多少?你甚至做过基本的printf调试吗?`?这是一个重复的问题-和以往一样,困难在于找到它的重复问题。@JonathanLeffler没问题:用谷歌搜索确切的标题:“大约511000个结果”,第一页上有这么多问题和回答。例如:你也需要关闭目录。例如,添加
closedir(pDir)
while()
-循环之后和
返回之前。如下文所述,检查名称是否不是
”。“
,否则您将进入无限递归。您的输出是什么?你甚至做过基本的printf调试吗?`?这是一个重复的问题-和以往一样,困难在于找到它的重复问题。@JonathanLeffler没问题:用谷歌搜索确切的标题:“大约511000个结果”,第一页上有这么多问题和回答。例如:你也需要关闭目录。例如,添加
closedir(pDir)
while()
-循环之后和
返回之前。如下文所述,请检查名称是否为“
或”
”。“
否则您将进入无限递归。最好使用
snprintf
@Chnossos详细信息:使用
snprintf()
而不检查
snprintf()
的结果可以处理一个问题,但会打开另一个作为
搜索目录(newDir)
可能会产生令人惊讶的结果(开放式失败、无限递归等)。更好地使用
snprintf
@Chnossos详细信息:使用
snprintf()
而不检查
snprintf()的结果
处理一个问题,但打开另一个作为
搜索目录(newDir)
可能会产生令人惊讶的结果(开放故障、无限递归等)。可疑OP也会在
”的
pDirect->d_name
中出现递归问题。
。”
。谢谢——在回答中添加了警告。可疑OP也会在
”的
pDirect->->->name
中出现递归问题
。谢谢——在答案中添加了警告