gpt4 book ai didi

c - 我需要为 Dirent 结构分配内存吗

转载 作者:行者123 更新时间:2023-11-30 14:20:16 25 4
gpt4 key购买 nike

  • 平台:Windows XP Service Pack 3
  • 编译器:Code::Blocks 版本 12.11

我目前正在编写一个程序,该程序将使用 POSIX 目录函数递归删除给定目录。但我对 readdir() 及其对应的 dirent 结构有问题。我在readdir的documentation中读到对函数的多次调用将覆盖函数返回的结构中保存的数据。所以我认为 readdir() 必须为结构本身分配内存,然后简单地将指针地址重新分配给捕获其返回值的结构。我测试了这个理论,我是正确的 readdir() 为其成员 d_name 分配了内存。我遇到的问题是,当目录流为空时,readdir 返回 NULL 指针,因此我使用带有条件 (dirent_ptr != NULL) 的 while 循环来迭代整个目录。但因为 readdir() 将处理该结构的内存分配,所以我只需声明一个 dirent 结构并让 readdir() 完成其工作。不幸的是,由于某种原因,不同的结构被初始化为 NULL(或者可能是我的编译器),所以我的循环永远不会启动,因为它的条件语句最初不是 true。所以我想我的问题是我在这里做错了什么?

这里是重要的变量声明和包含的库。请注意,所有这些变量都是全局声明的。

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

int recursive_delete(const char *path);
int file_delete(const char *path, int file_size);

struct dirent *direntp;
struct stat *statp;

struct switches
{
int verbose;
int no_prompt;
int continue_if_error;
int files_only;
}; struct switches switches;

我不是解析相对路径,而是简单地 cd 到作为参数给出的路径,然后使用 .和..要移动的通配符抛出目录,以便相对路径(d_names)有效。此外,开关结构仅包含命令行开关,应被忽略,我知道以下代码中的错误,但不幸的是我无法修复它们,因为我无法解决上述问题。

int recursive_delete(const char *path)
{
DIR *dirp;
int return_value = 0;
int recursive_return_value = 0;

if((chdir(path)) == -1)
{
perror("ERROR(3)");
return 1;
}
printf("CDED to \"%s\"\n", path);

dirp = opendir(".");
if(dirp == NULL)
{
perror("ERROR(4)");
return 1;
}
printf("OPENED \"%s\"\n", path);

while(direntp != NULL)
{
direntp = readdir(dirp);
if( (direntp == NULL) && (errno != 0) )
{
perror("ERROR(5)");
return 1;
}
printf("READ \"%s\" FROM \"%s\"\n", direntp->d_name, path);

if( (strcmp(direntp->d_name, ".")!=0) && (strcmp(direntp->d_name, "..")!=0) )
{
if((stat(direntp->d_name, statp)) == -1)
{
perror("ERROR(6)");
return 1;
}
printf("STATED \"%s\"\n", direntp->d_name);

if(S_ISREG(statp->st_mode))
{
printf("DELETING \"...\\%s\\%s\"\n", path, direntp->d_name);
return_value += file_delete(direntp->d_name, statp->st_size);
if( (!switches.continue_if_error) && (return_value != 0) )
{
break;
}
}
else if(S_ISDIR(statp->st_mode))
{
printf("\n\n\nCALLING RECURSIVE DELETE with \"%s\"\n", direntp->d_name);
recursive_return_value = recursive_delete(direntp->d_name);
return_value += recursive_return_value;

if( (!switches.continue_if_error) && (recursive_return_value != 0) )
{
break;
}

if( (!switches.files_only) && (recursive_return_value == 0) )
{
if((chdir("..")) == -1)
{
perror("ERROR(6)");
return 1;
}
printf("CDED BACK TO \"%s\" FROM \"%s\"\n", path, direntp->d_name);

if((rmdir(direntp->d_name)) == -1)
{
perror("ERROR(7)");
return 1;
}

if(switches.verbose)
{
printf("DELETED DIRECTORY \"...\\%s\\\"\n\n\n", direntp->d_name);
}
}
}
}
}

return return_value;
}

最佳答案

您的代码结构应如下所示(为了清楚起见,省略了大多数错误检查):

int recursive_delete(const char *path)
{
DIR* dirp = NULL;
int return_value = 0;
char* initial_cur_dir = malloc(1000);

getcwd(initial_cur_dir, 1000);
chdir(path);
dirp = opendir(".");

while (dirp != NULL)
{
struct dirent* direntp;
struct stat stat;

direntp = readdir(dirp);

if (direntp == NULL)
break;

stat(direntp->d_name, &stat);

if (S_ISDIR(statp->st_mode))
{
if (strcmp(direntp->d_name, ".") && strcmp(direntp->d_name, ".."))
{
return_value += recursive_delete(direntp->d_name);
}
}
else if (S_ISREG(statp->st_mode))
{
unlink(direntp->d_name);
}
}

if (initial_cur_dir != NULL)
{
chdir(initial_cur_dir);
rmdir(path);
}

ErrorLabel: // you should goto here when an error is detected

if (dirp != NULL)
{
closedir(dirp);
}

if (initial_cur_dir != NULL)
{
chdir(initial_cur_dir);
free(initial_cur_dir);
}

return return_value;
}

关于c - 我需要为 Dirent 结构分配内存吗,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15643857/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com