how to subtract one path from another?
So... I have a base path and a new path.New path contains in it base path. I need to see what is different in new path. Like we had /home/ and new path is /home/apple/one and I 开发者_运维百科need to get from it apple/one. note - when I would create some path from (homePath/diffPath) I need to get that /home/apple/one again. How to do such thing with Boost FileSystem?
Using stem() and parent_path() and walk backwards from the new path until we get back to base path, this works, but I am not sure if it is very safe. Be cautious, as the path "/home" and "/home/" are treated as different paths. The below only works if base path is /home (without trailing slash) and new path is guaranteed to be below base path in the directory tree.
#include <iostream>
#include <boost/filesystem.hpp>
int main(void)
{
namespace fs = boost::filesystem;
fs::path basepath("/home");
fs::path newpath("/home/apple/one");
fs::path diffpath;
fs::path tmppath = newpath;
while(tmppath != basepath) {
diffpath = tmppath.stem() / diffpath;
tmppath = tmppath.parent_path();
}
std::cout << "basepath: " << basepath << std::endl;
std::cout << "newpath: " << newpath << std::endl;
std::cout << "diffpath: " << diffpath << std::endl;
std::cout << "basepath/diffpath: " << basepath/diffpath << std::endl;
return 0;
}
Assuming you have:
namespace fs = std::filesystem; // or boost::filesystem
fs::path base = "/home/usera"
fs::path full = "/home/usera/documents/doc"
If you want to extract documents/doc
, you can do that with lexically_relative
:
fs::path diff = full.lexically_relative(base);
assert( diff == fs::path("documents/doc") );
This works for base = "/home/usera"
or base = "home/usera/"
. If full
does not contain base
, this may give you a pretty long path with lots of ..
instead of getting an error.
std::filesystem::path::lexically_relative
requires C++17
Other solution, if you know that newpath
really belongs to basepath
, could be:
auto nit = newpath.begin();
for (auto bit = basepath.begin(); bit != basepath.end(); ++bit, ++nit)
;
fs::path = path(nit, newpath.end());
精彩评论