我正在linux中创建一个c程序,用户可以输入要找到的目录名。一世 以下是我编写的代码,但没有得到正确的输出。我正在搜索所有目录,直到找到目录 我只是个初学者。
#include<unistd.h>
#include<dirent.h>
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<sys/stat.h>
#include<errno.h>
void findDir(char *dir, char *name)
{
DIR *dp;
struct dirent *entry;
struct stat statbuf;
if((dp = opendir(dir)) == NULL)
{
printf("\ncan not open directory: %s", name);
printf("\nDescription: %s", strerror(errno));
return;
}
chdir(dir);
while(( entry = readdir(dp)) != NULL)
{
lstat( entry->d_name, &statbuf);
if(S_ISDIR( statbuf.st_mode))
{
if( strcmp(name,entry->d_name) == 0)
{
printf("Dir found");
return;
}
findDir(entry->d_name, name);
}
}
chdir("..");
closedir(dp);
}
void main(int argc, char *argv[])
{
if( argc != 2 )
{
printf("Error");
}
else
{
findDir("/home", argv[1]);
}
}
请帮助!! 我在给出文档作为参数的同时获得了以下输出。实际上程序是无限的,我重复得到以下输出。这只是输出的一小部分。
无法打开目录:文件
描述:打开文件太多
无法打开目录:文件
描述:打开文件太多
无法打开目录:文件
描述:打开太多 找到filesDir
答案 0 :(得分:5)
问题是readdir()
不重入。它依赖于一个内部缓冲区,当你递归时,它会被覆盖。如果您使用的是POSIX标准,则可以尝试重新进入的readdir_r
。
或者,您可以在开始递归之前将目录读入列表,然后一次处理列表中的项目。这样你就可以在尝试潜入目录树中的下一级别之前阅读整个目录,并且当前级别的条目不会丢失到更深层次的覆盖。
答案 1 :(得分:2)
您将遇到的另一个问题(以及可能现在最影响您的问题)是特殊目录条目.
和..
将显示在{的结果中{1}} / opendir()
。您将需要使用以下内容检查并跳过这两个:
readdir()
答案 2 :(得分:0)
我快速浏览了一下。这是一些建议。
调试时,可以在调试器中单步执行,也可以至少放一些print语句来查看实际发生的情况。我在遍历目录的循环中放入printf()
,并发现它正在尝试访问..
目录,因此它会离开/home
并永远循环。
因此,在循环中,在执行任何其他操作之前,请测试entry->d_name
是"."
还是".."
,如果是,请跳过该目录条目(您可以使用continue
关键字。
确保在函数返回之前调用closedir(dp);
。例如,当您的代码打印消息can not open directory:
时,您的函数将返回而不关闭目录。顺便说一下,您应该在该错误消息中打印entry->d_name
,而不是name
。
错误Too many open files
是因为你的循环跟随..
所以它永远不会停止,并且它找到了大量无法打开的目录,因此错误退出时代码不会调用closedir()
意味着越来越多的目录被打开。
findDir()
以返回代码,说明它是否找到目标,并在此情况下停止程序。答案 3 :(得分:0)
您最好使用nftw(3)库函数,它可以通过文件树递归遍历。
如果您不被允许使用它,您至少可以研究它的来源,例如:来自MUSL libc文件src/misc/nftw.c,我发现它非常易读。
顺便说一句,您对lstat
的调用在您的代码中是错误的,您需要构建整个文件路径。
您需要在程序中使用gdb
调试器。您可能还希望使用strace
来了解它正在执行哪些系统调用(而strace
- 某些find
命令也会教您很多事情。)