如何使这个递归函数将其内容保存到链表中?

时间:2017-01-25 13:37:18

标签: c recursion linked-list filesystems

以下代码打开一个路径并递归读取目录并打印其中的文件。目前它只打印目录的路径,然后打印其中的每个文件,但我想实现一个链接列表,其中包含1个char *变量,其中包含每个访问过的文件的完整路径。

以下是代码:

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

void show_dir_content(char * path)
{
    DIR * d = opendir(path);                
    if(d==NULL) return;                     
    struct dirent * dir;                        
    while ((dir = readdir(d)) != NULL)      
    {
        if(dir-> d_type != DT_DIR)          // if the type is not directory just print it
            printf("\t%s\n",dir->d_name);
        else
            if(dir -> d_type == DT_DIR && strcmp(dir->d_name,".")!=0 && strcmp(dir->d_name,"..")!=0 )   // if it is a directory
            {
                char d_path[255];                               // here I am using sprintf which is safer than strcat
                sprintf(d_path, "%s/%s", path, dir->d_name);
                printf("%s\n",d_path);
                show_dir_content(d_path);                       
            }
    }
    closedir(d);                                        
}

int main(int argc, char **argv)
{
    show_dir_content(argv[1]);
    return(0);
}

用于链表的结构可以非常简单,例如:

typedef struct search search;
struct search {
    char *path;
    char *fileName;
    char *fullPathToFile;
    search *next;
};

我很难将malloc用于结构并在递归函数中创建实际的链表。任何帮助表示赞赏。

2 个答案:

答案 0 :(得分:1)

每次找到文件时都需要创建一个新的search节点。填写新节点,然后将其添加到列表末尾。

const char *path_format = "%s/%s";

// Modified to take a node ptr. This should be the last node in the list
// Returns a node ptr. This is the new last node in the list
search * show_dir_content(char * path, search *node)
{
    DIR * d = opendir(path);                
    if(d==NULL) return node;                     
    struct dirent * dir;                        
    while ((dir = readdir(d)) != NULL)      
    {
        if(dir-> d_type != DT_DIR) {
            // Found a file. Alloc a new search node and fill in
            // (TODO: You should check the return from malloc for failure)
            search *new_node = malloc(sizeof(search));
            // TODO: copy all the names. Hint: strdup
            new_node->next = NULL;
            // Append to end of list
            node->next = new_node;
            // Update node pointer to now point to the new node
            node = node->next;
        }
        else
            if(dir -> d_type == DT_DIR && strcmp(dir->d_name,".")!=0 && strcmp(dir->d_name,"..")!=0 )   // if it is a directory
            {
                // Not sure 255 chars will be enough....
                char d_path[255];                               // here I am using sprintf which is safer than strcat
                sprintf(d_path, path_format, path, dir->d_name);
                printf("%s\n",d_path);
                // Make sure you update the node pointer to reflect any
                // changes made in the recursive call
                node = show_dir_content(d_path, node);
            }
    }
    closedir(d);
    // Return the last node (this may be same as input parameter if no files found                               
    return node;
}

更新main以创建根节点并将其传递给函数

int main(int argc, char **argv)
{
    search root = {0};
    show_dir_content(argv[1], &root);
    // Note that root is a dummy node.
    // The list actually begins at root->next

    // Also, before you exit, free all mem
    search *node = root.next, *next;
    while (NULL != node) {
        free(node->path);
        free(node->fileName);
        free(node->fullPathToFile);
        next = node->next;
        free(node);
        node = next;
    }

    return(0);
}

答案 1 :(得分:0)

我认为你可以修改你的原型,添加一个struct search * param,它将成为你名单上的头脑。

当你需要在你的列表中放置一个元素时,只需在队列中添加一个节点(或者如果你想要在头部添加一个节点,但你需要一个struct search **而不是一个简单的指针。 然后,当你需要放置一个元素时,只需调用一个能够创建一个元素的函数并将它放在你想要的位置。 在那之后,你将只给每个递归调用你的列表的head ptr