如何在 Linux 上的 C 中查找目录及其子目录中的文件?
Posted
技术标签:
【中文标题】如何在 Linux 上的 C 中查找目录及其子目录中的文件?【英文标题】:How to find a file in a directory and its subdirectories in C on Linux? 【发布时间】:2021-08-06 18:12:15 【问题描述】:我想编写一个给定文件名的程序,在当前目录及其子目录中搜索该文件。应该打印包含该文件的子目录的名称。
但我的代码只打印子目录。
#include <dirent.h>
#include <stdio.h>
#include <string.h>
void listDir(char *path, char *name)
DIR *dir;
struct dirent *ent;
if ((dir = opendir(path)) != NULL)
while (( ent = readdir(dir)) != NULL)
if (ent->d_type == DT_REG && name == ent->d_name)
printf("%s\n", ent->d_name);
if (ent->d_type == DT_DIR && strcmp(ent->d_name, ".") != 0 && strcmp(ent->d_name, "..") != 0)
printf("%s\n", ent->d_name);
listDir("/home/dir1/ent->d_name", name);
closedir(dir);
void main()
listDir("/home/dir1", "file1");
【问题讨论】:
strcmp(ent-$
此处似乎缺少某些内容。
man nftw
....
@MikeCAT 谢谢
为什么不使用nftw()、scandir()或glob()呢?我真的希望新的 POSIX C 程序员被教导不要使用 opendir()/readdir()/closedir(),而是使用适当的 POSIX 接口:nftw()、scandir()、glob() 和 wordexp()。跨度>
【参考方案1】:
您要么需要跟踪完整路径,要么深入每个目录。 (如果您正在查看foo/bar/baz
,那么如果您在***目录中,opendir("baz")
将失败)。比如:
#include <dirent.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <limits.h>
#include <string.h>
void
listDir(char* path, const char *name)
DIR* dir;
struct dirent *ent;
char *end = strrchr(path, '\0');
if( (dir = opendir(path)) == NULL )
perror(path);
return;
else while( (ent = readdir(dir)) != NULL )
if( ent->d_type == DT_DIR && strcmp(ent->d_name, ".")
&& strcmp(ent->d_name, "..") )
snprintf(end, PATH_MAX - (end - path), "/%s",
ent->d_name);
listDir(path, name);
*end = '\0';
else if( !strcmp(ent->d_name, name) )
printf("%s\n", path);
closedir(dir);
int
main(int argc, char **argv)
char path[PATH_MAX];
char *defaults[] = NULL, NULL, ".", NULL;
if( argc < 2 )
printf("usage: %s name [path...]", argv[0]);
return EXIT_SUCCESS;
const char *name = argv[1];
if( argc < 3 )
argv = defaults;
for( argv += 2; *argv; argv += 1 )
/* getcwd(fullpath, PATH_MAX); */
snprintf(path, PATH_MAX, "%s", *argv);
listDir(path, name);
return 0;
【讨论】:
strrchr(path, '\0');
是一种计算字符串长度的创造性方法...【参考方案2】:
您的代码存在多个问题:
比较name == ent->d_name
不适用于字符串指针,您应该使用!strcmp(name, ent->d_name)
。
listDir("/home/dir1/ent->d_name", name);
不会神奇地 连接字符串。您应该使用 snprintf
或 asprintf
(在 linux 和 BSD 系统上)来构造子目录名称。
这是修改后的版本:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
void listDir(const char *path, const char *name)
DIR *dir;
struct dirent *ent;
if ((dir = opendir(path)) != NULL)
while ((ent = readdir(dir)) != NULL)
if (ent->d_type == DT_REG && !strcmp(name, ent->d_name))
printf("%s\n", path);
if (ent->d_type == DT_DIR && strcmp(ent->d_name, ".")
&& strcmp(ent->d_name, ".."))
char *subdir;
size_t len = strlen(path);
const char *sep = "/";
if (len && path[len - 1] == '/')
sep++;
if (asprintf(&subdir, "%s%s%s", path, sep, ent->d_name) > 0)
listDir(subdir, name);
free(subdir);
closedir(dir);
int main(int argc, char *argv[])
if (argc == 3)
listDir(argv[1], argv[2]);
else
fprintf(stderr, "usage: %s FILE DIR\n", argv[0]);
return 0;
【讨论】:
以上是关于如何在 Linux 上的 C 中查找目录及其子目录中的文件?的主要内容,如果未能解决你的问题,请参考以下文章
如何在使用查找时列出没有绝对路径的目录中的所有文件及其文件大小