Pra Sys
asked on
How to change dir when full path is not known in linux using c++?
I have a c++ program which processes a file and during that it creates few folders recursively at certain known path. The name of new folders are not known as they are created by another c++ program which is invoked internally by my program. One of the folder somewhere is "process". I need to change my current directory to "process" without directly knowing full path. Can someone tell how to do that?
For example - If I am running my program "sample" from /home/mumbaikar/cpp/sample , it creates input/1234/5678/abcd/proce ss under /home/mumbaikar/cpp/sample . I am only aware of input folder but not any folder after that till "process". Now I want to seek or change dir to "process".
How can I do it?
Thanks.
For example - If I am running my program "sample" from /home/mumbaikar/cpp/sample
How can I do it?
Thanks.
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER
Thanks for help both of you. I am using below code as of now. I will test and will see if that actually meets the user requiremets. I am actually storing all pathts of all directories under my app directory and then finding for "process" element or any other element. It will be only duering testing I will know if there are more than 1 "process" folders under my app directory -
populatePaths(string & path) {
string strDir;
string strFullPath;
char currDir[FILENAME_MAX];
if (GetCurrentDir(currDir, sizeof(currDir))) {
currDir[sizeof(currDir) - 1] = '\0';
cout << "Current Dir is " << currDir << endl;
}
DIR* dir = opendir(path.c_str());
if(dir == 0) {
cout << "Can not open directory '" << path << "'\n";
return 0;
}
struct dirent *d;
while( (d = readdir(dir)) != 0) {
if( d->d_type == DT_DIR && strcmp(d->d_name,".") != 0 &&
strcmp(d->d_name,"..") != 0) {
strFullPath = path + "/" + d->d_name;
cout << "Directory ---> " << d->d_name << " Path ------> " << strFullPath.c_str() << endl;
strDir = d->d_name;
myMap.insert(pair<string, string>(strDir, strFullPath));
populatePaths(strFullPath) ;
}
}
closedir(dir);
return 1;
}
populatePaths(string & path) {
string strDir;
string strFullPath;
char currDir[FILENAME_MAX];
if (GetCurrentDir(currDir, sizeof(currDir))) {
currDir[sizeof(currDir) - 1] = '\0';
cout << "Current Dir is " << currDir << endl;
}
DIR* dir = opendir(path.c_str());
if(dir == 0) {
cout << "Can not open directory '" << path << "'\n";
return 0;
}
struct dirent *d;
while( (d = readdir(dir)) != 0) {
if( d->d_type == DT_DIR && strcmp(d->d_name,".") != 0 &&
strcmp(d->d_name,"..") != 0) {
strFullPath = path + "/" + d->d_name;
cout << "Directory ---> " << d->d_name << " Path ------> " << strFullPath.c_str() << endl;
strDir = d->d_name;
myMap.insert(pair<string, string>(strDir, strFullPath));
populatePaths(strFullPath)
}
}
closedir(dir);
return 1;
}
Hi mumbaikar,
You may be able to get better control of the entire process if you'll run the program that is "invoked internally by my program" from a thread that is part of this program. Since both processes will share memory, the program that creates the folders may be able to write the path into shared memory.
Kent
You may be able to get better control of the entire process if you'll run the program that is "invoked internally by my program" from a thread that is part of this program. Since both processes will share memory, the program that creates the folders may be able to write the path into shared memory.
Kent
the code you posted probably will not do what you want when there are subfolders which have same name, for example a second 'abcd' in another branch.
instead of a map with key is folder name you better use a normal vector<string> and pass the folder name you were searching for, in example 'process', as second argument to PopulatePath. then the PopulatePath could add only those complete paths to result vector which have the name 'process'.
Sara
instead of a map with key is folder name you better use a normal vector<string> and pass the folder name you were searching for, in example 'process', as second argument to PopulatePath. then the PopulatePath could add only those complete paths to result vector which have the name 'process'.
Sara
by the way, adding to a std::map more easily is like
myMap[strDir] = strFullPath;
that would behave different for duplicate keys. while your insert would do nothing in case the strDir already exists, the above would overwrite the value.
both variants are logical flaws, though.
Sara
myMap[strDir] = strFullPath;
that would behave different for duplicate keys. while your insert would do nothing in case the strDir already exists, the above would overwrite the value.
both variants are logical flaws, though.
Sara
ASKER
@kdo:
The program that I run internally is developed by some other team and only binary executable is available to me. I can not make it write path anywhere in shared memory. But you were right, if we had that control, things would have been easier.
@sarabande:
the additional requirements of storing paths of more keywords made me write code like above. So apart from "process", I need to look for few more subfolders like "docs", "config" etc. You are right that if folder name repeats then above code will fail. Fortunately, in current situation there will be only one folder will be created with name "process", "docs" or "config".
Thanks
The program that I run internally is developed by some other team and only binary executable is available to me. I can not make it write path anywhere in shared memory. But you were right, if we had that control, things would have been easier.
@sarabande:
the additional requirements of storing paths of more keywords made me write code like above. So apart from "process", I need to look for few more subfolders like "docs", "config" etc. You are right that if folder name repeats then above code will fail. Fortunately, in current situation there will be only one folder will be created with name "process", "docs" or "config".
Thanks
SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER
I was able to search and collect full path as I wanted based on these responses. Great help. Appreciate that.
input/
input/1234/
input/1234/5678/
input/1234/5678/abcd/
all only have exactly one subfolder.
if that is true the the search for the process folder can be done in a simple loop and must not done recursively.
note, if the assumption is not true - for example because an older path to a process folder still exists - you would get problems to decide which of two or more process subfolders is the right one.
Sara