【发布时间】:2025-12-09 11:50:01
【问题描述】:
我有一个编程问题,希望有人能帮我解决。我正在尝试为工作中的一项任务学习 C 编程,并且我为自己设置了一个小项目,其中包括阅读文件树,其中包括获取有关每个文件的信息的所有子目录。
我遇到的问题是我的程序不会忽略以 / 结尾的目录路径。或 /.. 当它打印所有目录时,我想在子目录前面留出空间以提高可读性。
所以这部分出现了错误:
int isDir(const char *parent, char *name) {
struct stat st_buf; // file info
char buf[BUF_SIZE];
if (strcmp(name, ".") == 0 || strcmp(name, "..") == 0) {
return 0;
}
char *path = malloc(strlen(name) + strlen(parent) + 2);
//sprintf(char *buf, const char *format, [arg1],[arg2],...)
sprintf(path, "%s/%s", parent, name);
stat(path, &st_buf); //
return S_ISDIR(st_buf.st_mode); //directory
}
这是主函数和列表函数:
int list(const char *name) {
DIR *dirp = opendir(name);
struct dirent *dentry;
char buf[BUF_SIZE];
while ((dentry = readdir(dirp)) != NULL) {
char *dir_name = dentry->d_name;
printf(" %s\n", dir_name);
//if it's dir, then go into dir
if (isDir(name, dir_name)) { //name : parent, dir_name : child
chdir(dir_name);
getcwd(buf, BUF_SIZE);
list(buf);
}
}
closedir(dirp);
}
int main()
{
list(".");
return 0;
}
结果是这样的:
hm1.c Data lab1.txt result1 lab3.txt . .. . .. result2 lab3.txt . .. result3 lab3.txt . .. a.c . .. a.out
我要打印的结果
hm1.c Data lab1.txt result1 lab3.txt result2 lab3.txt result3 lab3.txt a.c a.out
【问题讨论】:
-
您的
isDir()函数每次在name中使用.或..以外的其他内容调用时都会泄漏内存。您还应该至少检查malloc()和opendir()— 也可以说是chdir()和getcwd()。 -
在打印任何内容之前,您需要额外检查
.和..,并且您可能需要将额外的深度参数传递给list,以便您可以缩进基于它。 -
printf(" %s\n", dir_name);中使用的dir_name在哪里定义、设置等?file_mode和my_passwd变量也未使用。请参阅有关制作 MCVE 的指南 (minimal reproducible example)。它们使人们更容易帮助您。您显示的代码似乎比原始代码有所减少,但并未最小化且无法验证。 -
在打印任何内容之前,我对它们进行了额外的检查,但这也不起作用:(深度参数是什么?@RetiredNinja
-
在
while ((dentry = readdir(dirp)) != 0)循环中,在打印任何内容之前使用if (strcmp(dentry->d_name, ".") == 0 || strcmp(dentry->d_name, "..") continue;——这样做也可以简化isDir()。 'depth' 参数将由list(".", 0);在main()和int list(const char *dir, int level) { …; list(buf, level + 1); … }中触发。您将使用级别编号来生成适当数量的空格。例如,printf("%.*s", level * 4, "");将在每个级别生成 4 个空格。