3

I have a path, for example, named

/my/path/test/mytestpath

, and I want to judge if it start with a given path, for example

/my/path

vulkanino
  • 9,074
  • 7
  • 44
  • 71
zhaojing
  • 585
  • 3
  • 11
  • 33
  • This sounds like a simple [begins with problem](http://stackoverflow.com/questions/931827/stdstring-comparison-check-whether-string-begins-with-another-string) unless you plan on expanding paths (`~` for example) – Joe Mar 09 '12 at 15:02
  • Even without expansion, it's not quite that simple, @Joe. The file *string* begins with `/my/pa`, but the *path* does not include it. – Rob Kennedy Mar 09 '12 at 15:07
  • 1
    You might need to normalize a path first, especially on a system like UNIX with special wildcards and symbolic links. – CashCow Mar 09 '12 at 15:07
  • @Joe, yes, it is a more begin with problem. – zhaojing Mar 09 '12 at 15:21

4 Answers4

7

The C++17 filesystem library is probably the most robust solution. If C++17 is not available to you, Boost.Filesystem provides an implementation for earlier C++ versions. Try something like:

bool isSubDir(path p, path root) 
{
    while(p != path()) {
        if(p == root) {
             return true;
        }
        p = p.parent_path();
    }
    return false;
}
ComicSansMS
  • 51,484
  • 14
  • 155
  • 166
  • +1. Probably what zhaojing really wanted to know; the current description sounds like he got stuck halfway through solving the problem. – MSalters Mar 09 '12 at 15:48
  • It might be nicer to use `equivalent` rather than `operator==`, depending on the behavior you want. – Sander De Dycker Mar 09 '12 at 15:57
1
  1. Substring the length of the string ( /my/path ) of the original (/my/path/test/mytestpath ) from the beginning.
  2. Check whether two strings are equal.
Mahesh
  • 34,573
  • 20
  • 89
  • 115
  • 1
    You have to consider checking for `/my/path/` or else `/my/pathSomeDeviatingPath/` will be a match. Note the `/`. – Mahesh Mar 09 '12 at 15:10
1

You can do a string compare of the number of characters in the shorter string.

The fact that the characters match of itself won't mean it is a sub-path because you need to check that the next character in the longer string is a '/'

In C you can use strncmp() which takes a length of characters.

In C++ you can use the same or string compare functions. The find() function will work for this but remember to also check that the next character in the main path is a directory separator.

You could "tokenize" your path but that is likely to not be worth it.

CashCow
  • 30,981
  • 5
  • 61
  • 92
-1

std::string::find() returns the index at which a string was found, with an index of 0 being the start of the string:

std::string path("/my/path/test/mytestpath");

// This will check if 'path' begins with "/my/path/".
//
if (0 == path.find("/my/path/"))
{
    // 'path' starts with "/my/path".
}
hmjd
  • 120,187
  • 20
  • 207
  • 252
  • hmjd, thanks for your help. But I need to judge if the path is start with "/my/path", not only contain. – zhaojing Mar 09 '12 at 15:03
  • 4
    This won't quite work though because if path is /my/path1/stuff it will appear to work. – CashCow Mar 09 '12 at 15:04
  • @KonradRudolph /test/mytestpath/my/path is correct according to std::find. But the OP wants whether it starts with /my/path/ – Mahesh Mar 09 '12 at 15:05
  • it works unless the OP wants to write portable code (converting the `/` for different systems). – vulkanino Mar 09 '12 at 15:06
  • @Mahesh No. The code will only find hits at the beginning of the string, not in the middle (but it was missing a trailing slash). – Konrad Rudolph Mar 09 '12 at 15:23