2012-04-11 81 views
0

我有一个walkThroughFunction递归调用的问题。 代码应该通过目录并计算子目录,如果它找到一个文件,它应该打开它并搜索某个字符串。代码只能通过一个目录。有人可以帮我弄这个吗。你会发现大括号错了一点。请忽略这些。递归目录和文件流和搜索字符串

int directories=0; 
void walkThroughDirectory(char *directory_name,char *searchString){ 

DIR * directory; 
struct dirent * walker; 
char d_name[PATH_MAX]; 
int path_length; 
char path[PATH_MAX]; 
directory=opendir(directory_name); 
if(directory==NULL){ 
    cout<<"Error"<<endl; 
    cout<<directory_name<<" Cannot be Opened"<<endl; 
    exit(10000); 
} 
while((walker=readdir(directory)) !=NULL){ 




    strcpy(d_name,walker->d_name); 
    cout<<directory_name<<"/"<<endl; 
    if (strcmp (d_name, "..") == 0 && 
      strcmp (d_name, ".") == 0){ 
     continue; 
    } 
    else{ 


     path_length =  snprintf(path,PATH_MAX,"%s/%s\n",directory_name,d_name); 
     cout<<"HELLO"<<endl; 
     cout<<path<<endl; 
     if (path_length >= PATH_MAX){ 
      cout<<"Path is too long"<<endl; 
      exit (1000); 
     } 
     if(walker->d_type==DT_DIR){ 
      cout<<"Hello"<<endl; 
      directories++; 
      walkThroughDirectory (path,searchString); 
     } 
     else if(walker->d_type==DT_REG){ 
      ifstream openFile; 
      openFile.open(path); 
      char line[1500]; 
      int currentLine = 0; 
      if (openFile.is_open()){ 
       while (openFile.good()){ 
        currentLine++; 
        openFile.getline(line, 1500); 
        if (strstr(line, searchString) != NULL) 
         cout<<path<<": "<<currentLine<<": "<<line<<endl; 
       } 
      } 
      openFile.close();  
     } 
     /* 
     struct stat directory_stat; 
     if (stat(path, &directory_stat) == -1){ 

      return; 
     } 
     if (S_ISDIR(directory_stat.st_mode)){ 
      cout<<"HELLO"<<endl; 

      directories++; 
      walkThroughDirectory(path, searchString); 
     } 
     else if (S_ISREG(directory_stat.st_mode)){ 

      ifstream openFile; 
      openFile.open(path); 
      char line[1500]; 
      int currentLine = 0; 
      if (openFile.is_open()){ 
       while (openFile.good()){ 
        currentLine++; 
        openFile.getline(line, 1500); 
        if (strstr(line, searchString) != NULL) 
         cout<<path<<": "<<currentLine<<": "<<line<<endl; 

       } 

      } 
      // it's a file so search for text in file 

     } 
     */ 

    } 

} 

if (closedir (directory)) 
{ 
    cout<<"Unable to close "<<directory_name<<endl; 
    exit (1000); 
} 
} 

int main(){ 

    char * name; 
    name=new char; 

    cout<<"Total Directories "<< directories<<endl; 



    name=get_current_dir_name(); 
    cout<<"Current Directory is: "<<name<<endl; 
    /* 
    cout<<"Now Enter The Desired Directory from the root or the current path"<<endl; 
    char *desiredDirectory; 
    desiredDirectory=new char; 
    cin>>desiredDirectory; 
    cout<<"Enter The String You want to search"<<endl; 
    char *searchString; 
    searchString=new char; 
    cin>>searchString; 
    */ 
    char ourpath[400]; 
    strcpy(ourpath,name); 

    walkThroughDirectory(ourpath,"diminutive"); 
    cout<<"Total Directories "<< directories<<endl; 


    return 0; 
} 
+0

为什么_你的大括号错位?如果您使用适当的缩进方案,您将能够更快速地修复大量错误。 – Bojangles 2012-04-11 16:34:01

+0

我正在努力解决这个问题。因为这是一个项目,我不得不放弃。因此,错位。对不起,你可以帮忙@JamWaffles – mobykhn 2012-04-11 16:39:44

回答

0

此代码有几个问题。首先,当您执行strcmp来检查d_name是否为“。”。或“..”,您需要使用OR,而不是AND。其次,当您拨打sprintf来创建您的c字符串path时,您不应该在字符串末尾添加换行符。这就是导致你的代码只能深入一层的原因。第三,当你打电话给get_current_dir_name时,它会为你做所有的malloc工作。你正在做的是为单个字符分配空间,这个字符本身不起作用,并不是API的正确用法。请参阅man page for get_current_dir_name

下面的代码解决了这些问题(并且也有适当的缩进)。

#include <iostream> 
#include <fstream> 
#include <stdlib.h> 
#include <unistd.h> 
#include <dirent.h> 
#include <limits.h> 
#include <string.h> 

int directories=0; 
void walkThroughDirectory(char *directory_name,char *searchString) 
{ 
    DIR *directory; 
    struct dirent *walker; 
    char d_name[PATH_MAX]; 
    int path_length; 
    char path[PATH_MAX]; 
    directory = opendir(directory_name); 

    if(directory == NULL) 
    { 
     std::cout << directory_name << " Cannot be Opened" << std::endl; 
     exit(1); 
    } 

    while((walker=readdir(directory)) != NULL) 
    { 
     strcpy(d_name, walker->d_name); 

     // Needs to be || not && 
     if (strcmp(d_name, "..") == 0 || strcmp(d_name, ".") == 0) 
     { 
      continue; 
     } 
     else 
     { 
      // No newline on the path name. 
      path_length = snprintf(path, PATH_MAX, "%s/%s", directory_name, d_name); 

      if (path_length >= PATH_MAX) 
      { 
       std::cout << "Path is too long" << std::endl; 
       exit(2); 
      } 

      if(walker->d_type == DT_DIR) 
      { 
       directories++; 
       walkThroughDirectory(path, searchString); 
      } 
      else if(walker->d_type==DT_REG) 
      { 
       std::ifstream openFile; 
       openFile.open(path); 
       char line[1500]; 
       int currentLine = 0; 

       if (openFile.is_open()) 
       { 
        while (openFile.good()) 
        { 
         currentLine++; 
         openFile.getline(line, 1500); 
         if (strstr(line, searchString) != NULL) 
         std::cout << path << ": " << currentLine << ": " << line << std::endl; 
        } 
       } 
       openFile.close();  
      } 
     } 
    } 

    if (closedir(directory)) 
    { 
     std::cout << "Unable to close " << directory_name << std::endl; 
     exit(3); 
    } 
} 

int main() 
{ 
    // get_current_dir_name() mallocs a string for you. 
    char *name; 

    name = get_current_dir_name(); 
    walkThroughDirectory(name, "matthew"); 
    free(name); 
    std::cout << "Total Directories: " << directories << std::endl; 

    return 0; 
}