开发者

how to subtract one path from another?

开发者 https://www.devze.com 2023-02-27 02:56 出处:网络
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

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());
0

精彩评论

暂无评论...
验证码 换一张
取 消