3

I am learning to use dirent.h. While the process is fascinating and interesting, I have ran into a problem with using d_name.

I want to do two things using d_name.

  1. recursively search through the sub-directories. To this, when I encounter DT_DIR type files, I will make recursive call to the function

    void iterateDirectory(char* filePath){
    DIR* dirPtr;
    dirent* entry;
    entry = readdir(dirPtr);
    ...
    }
    

    within itself using d_name of the directory as a new char* filePath parameter. So,

    if(dirEntry->d_type == DT_DIR){
    entry->d_name;
    iterateDirectory(entry->d_name);
    ...
    }  
    
  2. Open all files within a directory. To do this, when I encounter DT_REG files, I will create ifstream object and open the file using d_name. So,

    if(dirEntry->d_type == DT_REG){
    entry->d_name;
    ifstream fin(entry->d_name);
    if(fin.is_open)
        cout<<"Opened"<<endl;
    else
        cout<<"Not Opened"<<endl;
    ...
    }  
    

The problem I am running into, is that neither the void iterateDirectory() function nor the ifstream fin() seems to recognize the entry->d_name as a valid input. When I call the iterate function using d_name or use ifstream with entry->d_name, my checks to see if the directory or file is open fails. The function itself is working, as I've checked the exact same function with different char* inputs. The only problem I can think of is that my function is not taking in the absolute path as the parameter.

My questions is how can I find the absolute path of a given file or sub-directory at the point of iteration. My initial solution was to make use of "." as that is the current directory. Store the address of "." into a string, and append "\"+entry->d_name. But I think the syntax is wrong.

Am I right about the absolute path problem? or is there another problem I am missing? If it is the absolute path problem, what is the syntax for getting the absolute path of a file?

P.S.

I've been informed in the past to minimize the amount of code I upload onto stack overflow for questions, and I presented what I figure to be the smallest required code. In case the information presented above is insufficient, I am linking github page for the code.

https://github.com/ForeverABoy/dirent.h_practice/blob/master/directoryIterator.cpp

Any and all helps are appreciated. Thank you!

Ishiro Kusabi
  • 211
  • 2
  • 6
  • 13
  • 1
    `d_name` is the name of the file in the directory. If you `opendir()`ed a *filePath* of "foo/bar", and `d_name` is "baz", in order to open that file you obviously have to open "foo/bar/baz", and not just what you see in `d_name`. – Sam Varshavchik Nov 26 '16 at 00:40
  • Sam, Thank you for your help. I realize the problem is with absolute path, and I am trying to figure out a way to get the absolute path of a directory from given input. Using realpath(entry->d_name, buffer) did not help much because 1. the realpath gives me build directory of my code instead of the input directory. 2. even with the files build directory, it does not update the address for sub-directories. after going from foo to foo/bar, when it searchs for baz, the realpath() gives me foo/baz instead of foo/bar/baz. – Ishiro Kusabi Nov 26 '16 at 01:15
  • 1
    Use `realpath()` on the ***directory name*** to get the absolute path to the directory. Then append `d_name`. – Sam Varshavchik Nov 26 '16 at 01:16
  • The only way I can think of is to have a vector contain a string or char* version of the initial input for directory. so std::vector folders will initially have foo as an element. Then once I read in from foo, if the file is a directory (bar), I will add the entry->d_name to the vector. Then I will do folders[0].append("/"); folders[0].append(folders[1]); then I would call the recursive function at folders[0].c_str(); – Ishiro Kusabi Nov 26 '16 at 01:20
  • This maybe a stupid question, but is that different from doing realpath(entry->d_name, buffer)? What would be the syntax for using realpath on directory name? From your example of foo, would it be realpath(foo,buffer)? – Ishiro Kusabi Nov 26 '16 at 01:23
  • Reread the manual page for `realpath()`. Don't just read the words. Understand what it means, and everything should be crystal clear. – Sam Varshavchik Nov 26 '16 at 01:41
  • Thank you Sam! You are right. Understanding the manual made things so much clearer! I got everything working. – Ishiro Kusabi Nov 26 '16 at 02:52

1 Answers1

1

Thanks to Sam Varshavchik, I have figured out the problem.

The problem indeed was in not calling the functions using full path names. I knew this and immediately tried fixing it with realpath(). The problem was that I was using realpath on the entry->d_name instead of directory name.

realpath(entry->d_name, buffer);

This returned the build directory instead of the input directory. I assume it is because while running the code, the path from variable d_name would be indeed in the build directory.

char* fullPath = realpath(inputPath, buffer);

This gives me the actual path I entered. From there, I just turned the path into string and appended the path as I encountered directories or files.

Thanks again Sam. You are right. When I read and fully understood what realpath() manual was saying, it all made sense.

Ishiro Kusabi
  • 211
  • 2
  • 6
  • 13