我正在尝试在C中创建一个函数来擦除临时文件夹的所有内容并删除该文件夹
虽然我已经成功创建了代码来循环浏览文件并删除文件夹(这很简单)但是我无法使用unlink删除文件。
这是我正在使用的代码:
int delete_folder(char *foldername) {
DIR *dp;
struct dirent *ep;
dp=opendir(foldername);
if (dp!=NULL) {
readdir(dp); readdir(dp);
while (ep=readdir(dp)) {
char* cell = concatenate(concatenate(foldername, "\\"), "Bayesian Estimation.xlsx");//ep->d_name);
printf("%s\n", cell);
remove(cell);
printf("%s\n", strerror(errno));
}
closedir(dp);
}
if (!rmdir(foldername)) {return(0);} else {return(-1);}
}
我编写的代码对于所有文件都是完全有效的,但文件名中包含空格。经过一些测试,我可以保证unlink函数消除文件夹中的所有文件(即使文件名中包含特殊字符的文件)但如果文件名包含空格则会失败(但是,对于同一文件,如果删除空格(s) ),此功能再次起作用)。
还有其他人遇到过这个问题吗?而且,更重要的是,它可以解决/发明吗? (即使我直接引入空间逃逸序列,问题仍然存在) unlink提供的错误是"没有这样的文件或目录" (ENOENT)。请注意,文件确实位于引用位置(可以通过在变量 cell 中输出正确文件名的代码进行验证),如果我使用函数remove而不是unlink,也会出现此错误。
PS:函数 concatenate 是我自己制作的函数,它输出两个输入字符串的串联。
编辑: 代码是用Windows中的Codeblocks编写的 这是连接函数的代码:
char* concatenate(char *str1, char *str2) {
int a1 = strlen(str1), a2 = strlen(str2); char* str3[a1+a2+1];
snprintf(str3, a1+a2+2, "%s%s", str1, str2);
return(str3);
}
虽然你说这是一个可能(并且容易)的内存泄漏是正确的,但是功能'输入和输出是生成的代码,仅供个人使用,因此没有充分的理由担心它(没有真正需要万无一失的代码。)
答案 0 :(得分:1)
你说"使用unlink()
"但代码正在使用remove()
。你在哪个平台?您的平台是否存在通过运行外部命令来实现remove()
的危险,该命令不能正确处理文件名中的空格?在大多数系统中,这不会成为问题。
问题是您在打印错误之前没有检查remove()
的返回值。如果函数指示它生成错误,则只应打印错误。标准C(或POSIX)库中的任何函数都不会将errno
设置为零。此外,应报告标准错误的错误;这就是标准错误流的用途。
if (remove(cell) != 0)
fprintf(stderr, "Failed to remove %s (%d: %s)\n", cell, errno, strerror(errno));
else
printf("%s removed OK\n", cell);
我认为else
条款是一种临时措施,而您可以使代码正常运行。
看起来你也像一个众所周知的筛子一样泄漏记忆。您可以在cell
中捕获双连接操作的结果,但是您永远不会释放它。实际上,如果嵌套调用都分配内存,那么即使在循环结束时添加free(cell);
(在循环内部,在第二个printf()
之后添加concatenate()
,您也会发生泄漏我解构了)。如果concatenate()
每次都没有分配新内存(它返回一个指向静态分配内存的指针,那么我认为将一个字符串与concatenate()
的输出连接起来也很危险,可能会调用未定义的行为你将一个字符串复制到自身上。你需要仔细查看{{1}}的代码,和/或将其呈现给分析。
答案 1 :(得分:0)
非常感谢您的所有输入,在审核了您的评论并自己做了一些实验之后,我发现删除/取消链接无效,因为文件名只是临时保存在变量 cell (它足够长,可以正确打印到控制台,因此我的困惑)。在使用前正确存储我的文件名后,我的问题已经完全解决了 这是代码(我已经用文件名检查了它,因为我可以制作它们很复杂):
int delete_folder(char* foldername) {
DIR *dp;
struct dirent *ep;
dp=opendir(foldername);
if (dp!=NULL) {
readdir(dp); readdir(dp);
while (ep=readdir(dp)) {
char cell[strlen(foldername)+1+strlen(ep->d_name)+1];
strcpy(cell, concatenate(concatenate(foldername, "\\"), ep->d_name));
unlink(cell);
printf("File \"%s\": %s\n", ep->d_name, strerror(errno));
}
closedir(dp);
}
if (!rmdir(foldername)) {return(0);} else {return(-1);}
}
我意识到这是一个noob错误,因为我在C语言编程中有一段时间没有练习,所以...非常感谢你的帮助!