【问题标题】:How can I make this recursive function save its content into a linked list?如何使此递归函数将其内容保存到链表中?
【发布时间】:2017-01-25 13:37:18
【问题描述】:

以下代码打开一个路径并递归地读取目录并打印其中的文件。目前它只打印目录的路径,然后打印其中的每个文件,但我想实现一个链接列表,其中包含 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;
};

我只是很难为结构使用 mallocs 并在递归函数中创建实际的链表。任何帮助表示赞赏。

【问题讨论】:

  • 太宽泛的问题。请具体说明您遇到的确切问题。
  • @user694733 我的问题在问题的末尾指定。
  • 您列出了模糊的问题清单。您设法定义了结构类型。你的下一步是什么?假设它使用malloc 为其分配内存,你遇到了什么问题?编译错误信息?将您的问题分解为更小的问题,直到您有一个明确的问题我们可以回答。
  • @user694733 好的,所以我试着不那么含糊。 Here is the new question我问的更详细一点。你介意看看吗?

标签: c recursion linked-list filesystems


【解决方案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);
}

【讨论】:

  • 谢谢!我收到了 malloc 错误和“中止:陷阱 6”,但我现在正在查看您的回复。
  • 我问了一个新问题here。你能看看吗?
  • 您必须复制字符串。这意味着1)分配内存和2)复制。 strdup 为你做这件事。
  • 我很愚蠢,没有阅读您在代码中留下的提示。谢谢你。它修复了它。
【解决方案2】:

我认为您可以修改您的原型以添加一个 struct search * 参数,它将成为您列表的头指针。

当你需要在你的列表中添加一个元素时,只需在队列中添加一个节点(如果你愿意,也可以在头中添加一个节点,但你需要一个 struct search ** 而不是一个简单的指针。 然后,当您需要放置一个元素时,只需调用将创建一个元素并将其放置在您想要的位置的函数。 之后,您只需将列表中的head ptr 提供给每个递归调用

【讨论】:

  • 好的,我会尝试实现这一点。谢谢你的想法。
猜你喜欢
  • 2019-07-28
  • 2015-06-24
  • 2022-07-03
  • 1970-01-01
  • 2021-03-07
  • 1970-01-01
  • 2021-03-02
  • 1970-01-01
  • 2020-09-03
相关资源
最近更新 更多