Get relative path from two absolute paths?

Boost doesn't support this; it's an open issue — 1976 (Inverse function for complete) — that nevertheless doesn't seem to be getting much traction.

Boost doesn't support this; it's an open issue — #1976 (Inverse function for complete) — that nevertheless doesn't seem to be getting much traction. Here's a vaguely naive workaround that seems to do the trick (not sure whether it can be improved): #include #include #include #include /** * https://svn.boost. Org/trac/boost/ticket/1976#comment:2 * * "The idea: uncomplete(/foo/new, /foo/bar) => ../new * The use case for this is any time you get a full path (from an open dialog, perhaps) * and want to store a relative path so that the group of files can be moved to a different * directory without breaking the paths.An IDE would be a simple example, so that the * project file could be safely checked out of subversion.

" * * ALGORITHM: * iterate path and base * compare all elements so far of path and base * whilst they are the same, no write to output * when they change, or one runs out: * write to output, ../ times the number of remaining elements in base * write to output, the remaining elements in path */ boost::filesystem::path naive_uncomplete(boost::filesystem::path const p, boost::filesystem::path const base) { using boost::filesystem::path; using boost::filesystem::dot; using boost::filesystem::slash; if (p == base) return ". /"; /*! This breaks stuff if path is a filename rather than a directory, which it most likely is... but then base shouldn't be a filename so... */ boost::filesystem::path from_path, from_base, output; boost::filesystem::path::iterator path_it = p.begin(), path_end = p.end(); boost::filesystem::path::iterator base_it = base.begin(), base_end = base.end(); // check for emptiness if ((path_it == path_end) || (base_it == base_end)) throw std::runtime_error("path or base was empty; couldn't generate relative path"); #ifdef WIN32 // drive letters are different; don't generate a relative path if (*path_it!

= *base_it) return p; // now advance past drive letters; relative paths should only go up // to the root of the drive and not past it ++path_it, ++base_it; #endif // Cache system-dependent dot, double-dot and slash strings const std::string _dot = std::string(1, dot::value); const std::string _dots = std::string(2, dot::value); const std::string _sep = std::string(1, slash::value); // iterate over path and base while (true) { // compare all elements so far of path and base to find greatest common root; // when elements of path and base differ, or run out: if ((path_it == path_end) || (base_it == base_end) || (*path_it! = *base_it)) { // write to output, ../ times the number of remaining elements in base; // this is how far we've had to come down the tree from base to get to the common root for (; base_it! = base_end; ++base_it) { if (*base_it == _dot) continue; else if (*base_it == _sep) continue; output /= "../"; } // write to output, the remaining elements in path; // this is the path relative from the common root boost::filesystem::path::iterator path_it_start = path_it; for (; path_it!

= path_end; ++path_it) { if (path_it! = path_it_start) output /= "/"; if (*path_it == _dot) continue; if (*path_it == _sep) continue; output /= *path_it; } break; } // add directory level to both paths and continue iteration from_path /= path(*path_it); from_base /= path(*base_it); ++path_it, ++base_it; } return output; }.

Thanks for sharing that. I too spent some length of time searching in wonder of this missing feature – sehe Apr 24 at 20:25 This code does not work with version 3 of boost::filesystem due to the use of dot and slash, but with some modifications it can work. – Phineas May 3 at 18:35 1 @Phineas: Modified code posted as an answer would be appreciated :) – Tomalak Geret'kal May 3 at 21:43 I didn't have working code when I wrote the comment.

Comment out the using lines with dot and slash, then set _dot, _dots, and _sep to ". ", "..", and "/" respectively. I'm not sure what happened to dot and slash in V3 or whether there is a replacement.

– Phineas May 4 at 0:22 @Phineas: I think that would be a backwards step. I left them deliberately abstracted (albeit, admittedly, quite poorly). If dot and slash have been removed in v3 then I'd like to understand why, and I'd like to find out what abstract mechanism should replace them.

– Tomalak Geret'kal May 4 at 0:24.

I was just thinking about using boost filesystem library for the same task, but - since my application uses both Qt and Boost libraries, I decided to use Qt which does this task with one simple method: QString QDir::relativeFilePath ( const QString & fileName ) const It works like a charm and saved me a few hours of my life...

I cant really gove you an answer,but what I can give you is a way to a solution, that is you have to find the anglde that you relate to or peaks your interest. A good paper is one that people get drawn into because it reaches them ln some way.As for me WW11 to me, I think of the holocaust and the effect it had on the survivors, their families and those who stood by and did nothing until it was too late.

Related Questions