You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

将dirent结构体中文件/文件夹名存入链表后仅首个条目可打印的问题

问题分析与解决方案

你的代码存在两个核心问题,导致仅能输出第一个文件条目:

1. 链表节点未正确链接

原代码中,初始创建head节点后,cur指向head。第一次循环赋值cur->name并将cur->next设为NULL,随后cur = cur->next变为NULL。后续循环中虽然重新malloc了cur,但这个新节点并没有被链接到前一个节点的next指针上,导致链表断链,只有第一个节点在链表中。

2. 文件名指针复用问题

pDirent->d_name指向的是readdir内部的缓冲区,每次调用readdir都会覆盖这个缓冲区的内容。直接将cur->name赋值为该指针,会导致所有节点的name最终指向同一个缓冲区,显示的都是最后一次readdir读取的文件名(甚至可能出现未定义行为)。


修改后的代码

修复后的完整代码

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

typedef struct s_files
{
    char *name;
    struct s_files *next;
} t_files;

t_files *add_files()
{
    DIR *pDir;
    struct dirent *pDirent;

    t_files *head = NULL;
    t_files *cur = NULL;

    // 检查目录打开是否成功
    pDir = opendir(".");
    if (!pDir) {
        perror("opendir failed");
        return NULL;
    }

    while((pDirent = readdir(pDir)))
    {
        // 创建新节点并检查内存分配
        t_files *new_node = malloc(sizeof(t_files));
        if (!new_node) {
            perror("malloc failed");
            closedir(pDir);
            return head;
        }

        // 复制文件名,避免复用内部缓冲区
        new_node->name = strdup(pDirent->d_name);
        if (!new_node->name) {
            perror("strdup failed");
            free(new_node);
            closedir(pDir);
            return head;
        }

        new_node->next = NULL;

        // 将新节点链接到链表尾部
        if (!head) {
            head = new_node;
            cur = new_node;
        } else {
            cur->next = new_node;
            cur = new_node;
        }
    }

    closedir(pDir);
    return head;
}

void print_files(t_files *head)
{
    for ( ; head != NULL; head = head->next )
        printf( "%s ", head->name);
    printf("\n"); // 添加换行,输出更整洁
}

// 添加内存释放函数,避免内存泄漏
void free_files(t_files *head)
{
    t_files *tmp;
    while (head) {
        tmp = head;
        head = head->next;
        free(tmp->name);
        free(tmp);
    }
}

// 示例主函数
int main() {
    t_files *file_list = add_files();
    if (file_list) {
        print_files(file_list);
        free_files(file_list);
    }
    return 0;
}

修改说明

  • 链表构建逻辑优化:使用头指针和尾指针的方式,确保每个新节点都被正确链接到链表尾部,不会出现断链情况。
  • 文件名复制:使用strdup复制d_name的内容,每个节点拥有独立的文件名内存,避免缓冲区覆盖问题。
  • 错误检查:添加了opendir、malloc、strdup的错误检查,增强代码鲁棒性。
  • 内存释放:新增free_files函数,用于释放链表节点和复制的文件名内存,避免内存泄漏。

内容的提问来源于stack exchange,提问作者imbaled

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.29 15:26:28