2012-04-11 3 views
0

Ich habe ein Problem mit dem rekursiven Aufruf in der walkThroughFunction. Der Code soll Verzeichnisse durchlaufen und zählen die Unterverzeichnisse und wenn es eine Datei findet, sollte es öffnen und eine bestimmte Zeichenfolge suchen. Der Code läuft nur durch ein Verzeichnis. Kann mir jemand dabei helfen? Sie werden die Zahnspange ein wenig verloren finden. Bitte ignorieren Sie diese.Rekursive Verzeichnisse und Datei streaming und Suche Strings

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

Warum sind Ihre Zahnspangen fehlplatziert? Sie können eine Menge Fehler viel schneller beheben, wenn Sie ein richtiges Einrückungsschema verwenden. – Bojangles

+0

Ich habe versucht, das Problem in Eile zu lösen. weil es ein Projekt ist und ich es so schnell wie möglich geben muss. Daher die Fehlplatzierung. Tut mir leid, dass Sie @JamWaffles helfen können – mobykhn

Antwort

0

Dieser Code hat mehrere Probleme. Zuerst, wenn Sie die strcmp durchführen, um zu überprüfen, ob d_name "." oder "..", müssen Sie ein OR, kein UND verwenden. Zweitens, wenn Sie sprintf aufrufen, um Ihre C-Zeichenfolge path zu erstellen, sollten Sie keine neue Zeile am Ende der Zeichenfolge haben. Das hat dazu geführt, dass Ihr Code nur eine Stufe tief gegangen ist. Drittens, wenn Sie get_current_dir_name anrufen, macht es alle malloc Arbeit für Sie. Was Sie tun, ist die Zuweisung von Speicherplatz für ein einzelnes Zeichen, das nicht in sich selbst funktioniert und nicht eine korrekte Verwendung der API ist. Siehe die man page for get_current_dir_name.

Der folgende Code behebt diese Probleme (und hat auch eine korrekte Einrückung).

#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; 
}