7

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?

3 Answers 3

9

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;
}
Sign up to request clarification or add additional context in comments.

1 Comment

Instead of using while(tmppath != basepath) using while(!fs::equivalent(tmppath,basepath)) is more robust.
5

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

Comments

0

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

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.