如何使用递归函数(使用 C)在 Unix 中实现 find() 函数



>find [path]

我想要的方式显示在附图中。 我使用Mac终端。 我想做的只是使用查找功能显示路径。

我想用C语言实现UNIX-find((命令。 我写了一个代码,但我什么都不懂,我觉得它太乱了,所以我会向你们寻求帮助。 难道没有更简单的代码和更容易理解的代码吗?

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <dirent.h>
#include <unistd.h>
#define MAX_SIZE 1024
void do_ls(char[], char[]);
void print_error(int, char[]);
int main( int ac, char *av[] )
{
if( ac == 1 ) {
print_error(1, NULL);
}
else {
printf("%sn", av[1]);
do_ls(av[1], av[1]);
}
}
void do_ls( char path[], char dirname[] ) { // recursive func
DIR *dir_ptr;
struct dirent *direntp;
char buffer[MAX_SIZE] = "";
strcat(buffer, path);
if((dir_ptr = opendir(dirname)) == NULL) {
print_error(2, dirname);
}
else {
chdir(dirname);
while((direntp = readdir(dir_ptr)) != NULL) {
if(opendir(direntp->d_name) != NULL) {
if(strcmp(direntp->d_name, ".") != 0 && strcmp(direntp->d_name, "..") != 0) {
strcat(buffer, "/");
strcat(buffer, direntp->d_name);
printf("%sn", buffer);
do_ls(buffer, direntp->d_name);
strcpy(buffer, dirname);
if(strcmp(buffer, ".") != 0) {
strcpy(buffer, "./");
strcat(buffer, dirname);
}
}
}
else {
printf("%s/%sn", buffer, direntp->d_name);
if(strcmp(buffer, ".") != 0) {
chdir("..");
strcpy(buffer, ".");
}
}
}
}

}
void print_error(int error_num, char dirname[]) {
switch(error_num) {
case 1:
printf("usage : find [-H | -L | -P] [-EXdsx] [-f path] path ... [expression]n");
printf("        find [-H | -L | -P] [-EXdsx] -f path [path ...] [expression]n");
break;
case 2:
fprintf(stderr, "error: cannot open %sn", dirname);
break;
}
}

这是我的代码。 起初,我在没有缓冲区的情况下编写代码,但它不起作用。我以为我可以理解它并自己解决它,但我无法编写完美的代码,因为我对 C 没有足够的了解。

你有一个函数,它有 5 级嵌套条件块,这太多了,因为它更难阅读。您应该尝试创建较小的函数,具有一个或 2 个级别。此外,在递归函数上,它使用变量的次数越少,它对堆栈的消耗就越少。小函数经常 导致函数单独具有较小的内存占用。

与python不同,C不被视为尝试某些东西,看看它是否有效。您的第二个 opendir 可能会导致问题。假设它打开了目录/home/users/toto/work。您打开了目录,然后您将调用do_ls....将在其他时间/home/users/toto/work打开。打开同一目录两次...好吧,我不知道它是否有效,但它不好。不要使用 opendir 查看文件是否是目录,请使用stat ( man 2 )

您永远不会关闭目录。您将无法在大树上使用您的查找。在 C 中,您必须手动释放每个不是内存堆栈块的资源。

在这种情况下使用递归函数不是问题,在我看来,递归实现这种程序更容易。但最好打开一个目录,存储它的所有内容,关闭该目录,然后通读存储的内容。因此,您始终保留尽可能少的目录。

创建一个专用于concatenante路径组件的函数(并且会(,开始时,像这样的小功能通常调试起来有点无聊,你可能想要一个专用且易于测试的函数来完成这项工作。

最新更新