为您的
最初的
代码,你这样做
一旦
进入功能时:
strcpy(path_copy, path);
那么你这样做是为了
每个
当前目录中的文件或目录:
strcat(path_copy, "/");
strcat(path_copy, entry->d_name);
也就是说,如果你有文件
a
,则,
b
和
c
在当前目录中
/xx
这个
path_copy
变量将循环:
/xx/a /xx/a/b /xx/a/b/c
而不是正确的:
/xx/a /xx/b /xx/c
有了足够多的文件,您将很容易地耗尽为路径分配的1024个字节。
如果要解决此问题,则每次都应从头开始变量:
if ((strcmp(entry->d_name, ".") != 0) && (strcmp(entry->d_name, "..") != 0)) {
if (entry->d_type == DT_DIR) {
strcpy(path_copy, path);
strcat(path_copy, "/");
strcat(path_copy, entry->d_name);
rmrf(path_copy);
remove(path);
} else {
sprintf(path_copy, "%s/%s", path, entry->d_name);
remove(path_copy);
}
}
您会注意到,我对您的初始条件做了一些修改,使其更有意义(仅当文件既不是
.
也没有
..
)。
我还展示了
else
子句,使用
sprintf
而不是一套
strcpy/strcat
呼叫。您可以在
if
子句,如果您愿意的话,我已经使用旧方法保留了它,这样您就可以看到所需要做的只是添加初始路径。
还有一些额外的要点,适用于您的第一个和/或第二个代码段:
-
你还应该确保
自由的
在从函数返回之前,您在每个级别分配的内存
closedir()
和
return
。
-
你
从不
需要强制转换的返回值
malloc
自a
void *
可以隐式转换为任何其他类型的指针。事实上,这样做是危险的,因为它可以隐藏某些细微的错误。
-
同样,你
从不
需要乘以
sizeof(char)
-根据定义,这始终是一个问题。
-
您可以移动
path\u复制
到
之前
文件/目录检查,因为它对这两个部分都是通用的。
-
最后,如果您正在处理的目录实际上不存在,那么您将遇到麻烦
opendir
将返回NULL,您将立即尝试将其传递给
readdir
。
考虑到所有这些,我将从以下程序开始
步行
并打印出它找到的所有文件。一旦您对此感到满意,就可以在删除的位中重新添加:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <dirent.h>
int rmrf(char *path) {
char *path_copy = malloc(1024);
DIR *directory = opendir(path);
if (directory != NULL) {
struct dirent *entry = readdir(directory);
while (entry != NULL) {
if ((strcmp(entry->d_name, ".") != 0) && (strcmp(entry->d_name, "..") != 0)) {
sprintf(path_copy, "%s/%s", path, entry->d_name);
if (entry->d_type == DT_DIR) {
rmrf(path_copy);
puts(path);
} else {
puts(path_copy);
}
}
entry = readdir(directory);
}
closedir(directory);
}
free(path_copy);
return 0;
}
主代码只是一个驱动程序,用于确保正确设置思考。在运行之前,请确保(在当前目录中)没有
paxtest
或
paxtest2
要保留的文件或目录。
int main(void) {
system("rm -rf paxjunk");
system("mkdir paxjunk");
system("touch paxjunk/0.txt");
system("mkdir paxjunk/1");
system("touch paxjunk/1/1.txt");
system("mkdir paxjunk/2");
system("touch paxjunk/2/2.txt");
rmrf("paxjunk");
puts("===");
system("rm -rf paxjunk2");
rmrf("paxjunk2");
puts("===");
system("rm -rf paxjunk");
return 0;
}
运行此操作时,您应该看到它正常工作:
paxjunk/0.txt
paxjunk/1/1.txt
paxjunk
paxjunk/2/2.txt
paxjunk
===
===