我正在尝试以递归方式在目录中搜索文件,如果文件与给定文件匹配,则输出该文件:
static int *search(char *path, const char *request, int depth, bool verbose)
{
DIR *dir;
struct dirent *ent;
char *start_dir = strcmp(path, "/") == 0 ? "root" : path;
printf("\nStarting in '%s' directory..\n\n", start_dir);
if ((dir = opendir(path)) != NULL)
{
while ((ent = readdir(dir)) != NULL)
{
if (verbose == true)
{
printf("Searching directory %s for file %s\n", ent->d_name, request);
}
if (ent->d_type == DT_DIR)
{
if ((strlen(path) + strlen(ent->d_name) + 1) > PATH_MAX)
{
puts("Path to long, cannot continue..");
}
else
{
if (ent->d_name == DT_DIR && strcmp(ent->d_name, ".") != 0 &&
strcmp(ent->d_name, "..") != 0 )
{
printf("%s\n", ent->d_name);
}
}
}
}
}
return 0;
}
这将有效,但不会输出目录中的文件或目录。例如:
@ubuntu:~/bin/c/find-files$ ./utilis test / -V
Initialized to search for file: 'test'..
Starting in 'root' directory..
Searching directory vmlinuz.old for file test
Searching directory boot for file test
Searching directory home for file test
Searching directory libx32 for file test
Searching directory lib32 for file test
Searching directory lib64 for file test
Searching directory initrd.img for file test
Searching directory srv for file test
Searching directory usr for file test
Searching directory . for file test
Searching directory cdrom for file test
Searching directory tmp for file test
Searching directory initrd.img.old for file test
Searching directory bin for file test
Searching directory .. for file test
Searching directory proc for file test
Searching directory lib for file test
Searching directory var for file test
Searching directory dev for file test
Searching directory sys for file test
Searching directory media for file test
Searching directory root for file test
Searching directory snap for file test
Searching directory run for file test
Searching directory sbin for file test
Searching directory opt for file test
Searching directory lost+found for file test
Searching directory mnt for file test
Searching directory vmlinuz for file test
Searching directory etc for file test
如何重构此函数以便在所有目录和子目录中递归搜索给定的文件名?
答案 0 :(得分:0)
正如许多人的评论中已经指出的那样。丢失的递归调用(函数调用自身)不会递归您的代码。你有很多错误。不检查各种系统调用的错误,忘记关闭目录流。我不知道您希望通过各种参数int depth
,bool verbose
实现什么目标。但这是寻找特定文件并在成功时返回0 --> EXIT_SUCCESS
并在失败时返回1 -->EXIT_FAILURE
的另一种方式。
使用系统调用时会出现各种错误,有些设置errnos,这对于查看它们并打印到STDERR非常重要
#include <stdio.h>
#include <stdlib.h>
#include <dirent.h>
#include <errno.h>
#include <string.h>
#define DEBUG 1
static int search(char *path,const char *file){
DIR *dir;
char *slash = "/";
int ret = 1;
struct dirent *entry;
//checking if it failed to open and report errors to STDERR
if((dir = opendir(path)) == NULL){
fprintf(stderr,"opendir: %s\n",strerror(errno));
return EXIT_FAILURE;
}
while ((entry = readdir(dir))){
//if is . or .. we continue to prevent winging back and forth
if(strcmp(entry->d_name,".") == 0 || strcmp(entry->d_name,"..") == 0)
continue;
//we check if the path has already a / if not we add one
int length = strlen(path);
if(path[length-1] != '/'){
slash = "/";
}
length += strlen(entry->d_name)+2;
char *newpath = malloc(length);
if (!newpath){
fprintf(stderr,"malloc: %s\n",strerror(errno));
break;
}
snprintf(newpath,length,"%s%s%s",path,slash,entry->d_name);
if(strcmp(entry->d_name,file) ==0){
#if DEBUG
printf("Was found here %s\n",newpath);
#endif
ret = EXIT_SUCCESS;
break;
}
//checking if is a directory to do a recursive call
// using DT_DIR to avoid the use of lstat or stat
// if not directory we free the memory and move on
if(entry->d_type == DT_DIR)
search(newpath,file);
else{
free(newpath);
continue;
}
free(newpath);
}
if(closedir(dir) != 0){
fprintf(stderr,"closedir: %s\n",strerror(errno));
return EXIT_FAILURE;
}
return ret;
}
int main() {
char *file = "algo.c";
int ret = search("/",file);
printf("%d The file %s was %s\n",ret,file,(ret == 0 ? "found":"not found"));
return 0;
}
将DEBUG设置为1
在这里找到/Users/addodennis/CLionProjects/BluePrint/algo.c
找到了algo.c文件
将DEBUG设置为0
找到文件algo.c