无法递归访问子文件夹

时间:2017-03-27 04:55:06

标签: c linux recursion directory filesystems

我正在尝试构建一个程序,以递归方式列出目录中的所有文件夹和文件,以及它们的文件大小。我还在第一部分工作,因为程序似乎只是深入一级子文件夹。

有人能在这里发现问题吗?我被卡住了。

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

void listdir(const char *name) {
    DIR *dir;
    struct dirent *entry;
    int file_size;

    if (!(dir = opendir(name)))
        return;
    if (!(entry = readdir(dir)))
        return;

    do {
        if (entry->d_type == DT_DIR) {
            char path[1024];
            if (strcmp(entry->d_name, ".") == 0 || strcmp(entry->d_name, "..") == 0)
                continue;
            printf("./%s\n", entry->d_name);
            listdir(entry->d_name);
        }
        else
            printf("./%s\n", entry->d_name);
    } while (readdir(dir) != NULL);
    closedir(dir);
}

int main(void)
{
    listdir(".");
    return 0;
}

2 个答案:

答案 0 :(得分:3)

第一个问题是在while条件下,你放弃了readdir的返回值,它应该被分配给条目。

此外,在递归调用listdir时,您应该在路径前添加父名称,否则它将始终从当前工作目录中搜索。 试试这个版本:

void listdir(const char *name) {
    DIR *dir;
    struct dirent *entry;
    int file_size;

    if (!(dir = opendir(name)))
            return;

    while ((entry = readdir(dir)) != NULL) {   // <--- setting entry
            printf("%s/%s\n", name, entry->d_name);
            if (entry->d_type == DT_DIR) {
                    char path[1024];
                    if (strcmp(entry->d_name, ".") == 0 || strcmp(entry->d_name, "..") == 0)
                            continue;
                    sprintf(path, "%s/%s", name, entry->d_name);  // <--- update dir name properly by prepend the parent folder.
                    listdir(path);
            }
    }
    closedir(dir);
}

int main(void)
{
    listdir(".");
    return 0;
}

答案 1 :(得分:2)

以下是对代码的最小修复。我冒昧地在这里使用非标准的$data = array(); $toJson = array( 'success' => 'true', 'ViewSet' => array(), ); $toJson['ViewSet']['header'] = $this->load->view('Header/header', $data, true); $toJson['ViewSet']['leftpanel'] = $this->load->view('leftpanel/leftpanel', $data, true); $toJson['ViewSet']['create'] = $this->load->view('user/create', $data, true); $this->output ->set_content_type('application/json') ->set_output(json_encode($toJson)); ;如果你没有使用glibc,你应该使用asprintf或类似的。

最值得注意的是,snprintf的路径必须是当前工作目录的完整相对路径;或绝对路径。但是listdir中的那个只是文件的基本名称。因此,它必须与传递给entry->d_name的路径连接在一起。我还在此处将不合适的listdir ... do更改为while循环。

while