我在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 :(得分:0)
此代码有几个问题。首先,当您执行strcmp
以检查d_name
是否为“时”。或“..”,你需要使用OR,而不是AND。其次,当您调用sprintf
来创建c-string path
时,您不应该在字符串的末尾添加换行符。这就是导致您的代码只能达到一个深度的原因。第三,当您致电get_current_dir_name
时,它会为您完成所有malloc
工作。你正在做的是为一个char分配空间,这本身不会起作用,也不能正确使用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;
}