C 递归列表

C 递归列表,c,recursion,ls,C,Recursion,Ls,我在尝试在C上实现类似ls-R的东西时遇到了问题,问题是我需要列表递归地列出从给定目录开始的所有内容,然后处理从列表中获得的常规文件。 这就是我到目前为止所做的: void ls(char* path){ DIR *directory; struct dirent *filei; struct stat stats; directory = opendir(path); if (directory != NULL) { whi

我在尝试在C上实现类似ls-R的东西时遇到了问题,问题是我需要列表递归地列出从给定目录开始的所有内容,然后处理从列表中获得的常规文件。 这就是我到目前为止所做的:

 void ls(char* path){
    DIR *directory;
    struct dirent *filei;
    struct stat stats;
    directory = opendir(path);
    if (directory != NULL)  
    {
        while ((filei=readdir(directory))!=NULL){
            stat(filei->d_name, &stats);    
            printf(" %s\n", filei->d_name); 
            if (S_ISDIR(stats.st_mode)){
                char *buf = malloc(strlen(path)+strlen(filei->d_name)+2);
                strcpy(buf,path);
                strcat(buf,"/");
                strcat(buf,filei->d_name);
                ls(buf);
            }
        }
        closedir(directory);
    }
    else{
        printf("Error.\n");     
    }
}
它根本不起作用,它显示的文件甚至不在我正在使用的文件夹中。 有什么想法吗?
谢谢。

您不能再次访问。和条目。您至少可以无限地递归到同一个目录上,或者返回得很糟糕。过滤器:

if (!strcmp(filei->d_name,".") && (!strcmp(filei->d_name,"..")) ls(buf);
您还必须统计到完整路径:

char *buf = malloc(strlen(path)+strlen(filei->d_name)+2);
strcpy(buf,path);
strcat(buf,"/");
strcat(buf,filei->d_name);
stat(buf, &stats);
if (S_ISDIR(stats.st_mode)) {
  if (!strcmp(filei->d_name,".") && (!strcmp(filei->d_name,"..")) {
    ls(buf);
  }
}

你不能再回到你的生活中。和条目。您至少可以无限地递归到同一个目录上,或者返回得很糟糕。过滤器:

if (!strcmp(filei->d_name,".") && (!strcmp(filei->d_name,"..")) ls(buf);
您还必须统计到完整路径:

char *buf = malloc(strlen(path)+strlen(filei->d_name)+2);
strcpy(buf,path);
strcat(buf,"/");
strcat(buf,filei->d_name);
stat(buf, &stats);
if (S_ISDIR(stats.st_mode)) {
  if (!strcmp(filei->d_name,".") && (!strcmp(filei->d_name,"..")) {
    ls(buf);
  }
}

下面对代码进行的返工在完整文件路径上调用stat,跳过。和目录,修复内存泄漏并添加少量错误处理:

#define SEPARATOR "/"

void ls(const char *path)
{
    DIR *directory = opendir(path);

    if (directory != NULL)  
    {
        struct dirent *filei;

        while ((filei = readdir(directory)) != NULL)
        {
            if (strcmp(filei->d_name, ".") == 0 || strcmp(filei->d_name, "..") == 0)
            {
                continue;
            }

            char *buffer = malloc(strlen(path) + strlen(filei->d_name) + strlen(SEPARATOR) + 1);
            strcat(strcat(strcpy(buffer, path), SEPARATOR), filei->d_name);

            struct stat stat_buffer;

            if (stat(buffer, &stat_buffer) == 0)
            {   
                printf("%s\n", buffer); 

                if (S_ISDIR(stat_buffer.st_mode))
                {
                    ls(buffer);
                }
            }
            else
            {
                perror(NULL);
            }

            free(buffer);
        }

        closedir(directory);
    }
    else
    {
        perror(NULL);     
    }
}

看看它是否对您更有效。

下面对代码进行的返工调用了完整文件路径上的stat,跳过了。和目录,修复内存泄漏并添加少量错误处理:

#define SEPARATOR "/"

void ls(const char *path)
{
    DIR *directory = opendir(path);

    if (directory != NULL)  
    {
        struct dirent *filei;

        while ((filei = readdir(directory)) != NULL)
        {
            if (strcmp(filei->d_name, ".") == 0 || strcmp(filei->d_name, "..") == 0)
            {
                continue;
            }

            char *buffer = malloc(strlen(path) + strlen(filei->d_name) + strlen(SEPARATOR) + 1);
            strcat(strcat(strcpy(buffer, path), SEPARATOR), filei->d_name);

            struct stat stat_buffer;

            if (stat(buffer, &stat_buffer) == 0)
            {   
                printf("%s\n", buffer); 

                if (S_ISDIR(stat_buffer.st_mode))
                {
                    ls(buffer);
                }
            }
            else
            {
                perror(NULL);
            }

            free(buffer);
        }

        closedir(directory);
    }
    else
    {
        perror(NULL);     
    }
}

看看它是否对您更有效。

这是使用文件/目录操作时的常见问题。d_名称不是完整路径。因此,除非当前目录是包含该文件/目录的目录,否则无法对其进行统计。opendir不会更改当前目录。需要在调用stat.或构造完整路径名之前调用chdir。您还需要过滤掉。和条目。否则你将以infinete递归结束。这解决了无限递归问题,但我还不能让它工作,我不是已经用它构建了完整的路径吗?`char*buf=mallocstrlenpath+strlenfilei->d_name+2;`strcpybuf,路径;`strcatbuf,/;strcatbuf,filei->d_name;在您发布的代码中,您正确地创建了完整的路径名,但没有足够早让stat使用它-请参阅我对代码的修改这是使用文件/目录操作时的常见问题。d_名称不是完整路径。因此,除非当前目录是包含该文件/目录的目录,否则无法对其进行统计。opendir不会更改当前目录。需要在调用stat.或构造完整路径名之前调用chdir。您还需要过滤掉。和条目。否则你将以infinete递归结束。这解决了无限递归问题,但我还不能让它工作,我不是已经用它构建了完整的路径吗?`char*buf=mallocstrlenpath+strlenfilei->d_name+2;`strcpybuf,路径;`strcatbuf,/;strcatbuf,filei->d_name;在您发布的代码中,您正确地创建了完整的路径名,但没有足够早让stat使用它-请参阅我的代码返工