我正在尝试通过所有子目录搜索作为参数给出的文件。我的代码的问题是,当它到达一个不是目录的文件时,它会以perror("Error opening the directory\n");
停止。
我无法找到克服这个问题的方法。我尝试了另一个if(S_ISREG...)
,但它没有用。
include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <dirent.h>
#include <string.h>
void check_file_existence(char *dirName,char *file){
struct stat *metadata;
char name[1000];
struct dirent *dirEntry;
struct stat bufstat;
DIR *dir;
dir = opendir(dirName);
if (dir==NULL)
{
perror("Error opening the directory\n");
exit(1);
}
while ((dirEntry = readdir(dir))!=NULL){
lstat(dirEntry->d_name,&bufstat);
if(S_ISDIR(bufstat.st_mode)){
if (strcmp(dirEntry->d_name,".")==0 || strcmp(dirEntry->d_name,"..")==0){
continue;
}
sprintf(name,"%s/%s",dirName,dirEntry->d_name);
printf("%s\n",name);
check_file_existence(name,file);
}
}
closedir(dir);
}
int main(int argc,char **argv){
if (argc!=3){
perror("Number of arguments is wrong.\n");
exit(1);
}
check_file_existence(argv[1],argv[2]);
}
答案 0 :(得分:1)
这是您的代码,其中有一些简化的功能可以偶然地解决您的错误,还有两项改进。现在,它可以递归搜索目录树,以查找指定文件的首次出现。
我们使用dirEntry结构识别文件类型,并添加strcmp()来检查指定的文件。在dirEntry结构中使用d_type是确定文件类型的最简单方法,因此往往会降低错误率。
我们检查输入中是否有多余的斜杠。输入上的额外斜杠不会停止任何操作,但会使输出不太清晰。
为方便调试,我们大量使用了printf(),并添加了一个例程以字节转储dirEntry结构的内容,以帮助您更详细地了解正在发生的事情,因为它递归并循环遍历了目录和文件。
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <dirent.h>
#include <string.h>
void debugbytes( char *s, unsigned short nlen, char dtype, char *nameptr ) {
int n;
printf( "\n%d %x ", nlen, dtype );
switch( dtype )
{
case DT_BLK:
printf( "BLK" );
break;
case DT_CHR:
printf( "CHR" );
break;
case DT_DIR:
printf( "DIR" );
break;
case DT_FIFO:
printf( "FIFO" );
break;
case DT_LNK:
printf( "LNK" );
break;
case DT_REG:
printf( "REG" );
break;
case DT_SOCK:
printf( "SOCK" );
break;
case DT_UNKNOWN:
printf( "UNKOWN" );
break;
default:
printf( "not recognized" );
}
printf( " %s :", nameptr );
for (n = 0; n < nlen; n++ ) {
printf( "%x", s[n] );
}
printf( "\n" );
}
void check_file_existence(char *dirName,char *file){
DIR *dir;
struct dirent *dirEntry;
char name[1000];
printf( "opening %s\n", dirName );
dir = opendir(dirName);
if (dir==NULL)
{
perror("Error opening the directory\n");
exit(1);
}
while ((dirEntry = readdir(dir))!=NULL){
debugbytes( (char *) dirEntry, dirEntry->d_reclen, dirEntry->d_type, dirEntry->d_name );
if ( dirEntry->d_type == DT_DIR ) {
if (strcmp(dirEntry->d_name,".")==0 || strcmp(dirEntry->d_name,"..")==0){
continue;
}
printf( "directory\n" );
sprintf(name,"%s/%s",dirName,dirEntry->d_name);
printf("\n%s\n",name);
check_file_existence(name,file);
}
else if ( dirEntry->d_type == DT_REG ) {
printf( "file %s/%s\n", dirName, (char *)dirEntry->d_name );
if ( !strcmp( dirEntry->d_name, file ) ) {
printf( "file found\n" );
break;
}
}
}
closedir(dir);
}
int main(int argc,char **argv){
char dirspec[256] = { 0 };
int n;
if (argc!=3){
perror("Number of arguments is wrong.\n");
exit(1);
}
n = strlen( argv[1] );
while( (n > 1) && argv[1][n-1] == '/' ) n--;
strncpy(dirspec, argv[1], n );
check_file_existence( dirspec, argv[2] );
}
这是示例输出:
$ ./temp1 gEDA/ 1206P.fp
opening gEDA
.
.
.
32 4 DIR Footprints :3b04250000ffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f2004466f6f747072696e7473004
directory
.
.
.
32 8 REG 1206P.fp :ffffff8084250000ffffffd0ffffffff12ffffffeb7afffffff77052200831323036502e6670054ffffffa7ffffffce8
file gEDA/Footprints/1206P.fp
file found
$