-3

Assuming a file & a folder does exist, I want a function to check if the file is contained by the folder.

For example: /a/b contains /a/b/c/d.e, /a/b contains /a/b/c.d, /a/b does not contain /a/b/../c/d.e.

What I get now is to normalize the path, then compare the prefix part. Is there some clean and simple way to do this?

heLomaN
  • 1,634
  • 2
  • 22
  • 33
  • https://en.cppreference.com/w/cpp/experimental/fs – Jesper Juhl Mar 04 '20 at 16:23
  • @JesperJuhl: Or maybe https://en.cppreference.com/w/cpp/filesystem/exists ? – Fred Larson Mar 04 '20 at 16:25
  • Another way... https://stackoverflow.com/questions/4316442/stdofstream-check-if-file-exists-before-writing (and all the linked answers inside) – Jose Mar 04 '20 at 16:26
  • 1
    Normalizing a path is actually a bit tricky. It's not simply string manipulation rules, because if `/a/b` is a soft link to `/q/r/s` then `/a/c/d.e` ≠ `/q/r/s/c/d.e` on the file system. – Eljay Mar 04 '20 at 16:26
  • @Fred I just wanted to provide a link to the main filesystem library overview page. I assume OP can then read from there and find the specifics needed + maybe also discover more useful stuff. – Jesper Juhl Mar 04 '20 at 16:28
  • http://man7.org/linux/man-pages/man3/canonicalize_file_name.3.html may also be of interest. – Jesper Juhl Mar 04 '20 at 16:29
  • @JesperJuhl https://en.cppreference.com/w/cpp/header/filesystem is the better link, then. I believe all main compilers have graduated `` out of experimental. – sweenish Mar 04 '20 at 16:36
  • @Jose It's my fault as not make it clear. The file does exist. So I don't need to check if it exist, and what I want is to check if the file lies in the folder or subfolder of it. – heLomaN Mar 04 '20 at 16:38

2 Answers2

1

I will assume that the file path is something like this: C:\Program Files\Important\data\app.exe while the folder path is something like this: C:\Program Files And so for that you may want to try this code:

#include <iostream>
#include <string>
using namespace std;
int main()
{
    string filePath, folderPath;
    cout << "Insert the full file path along with its name" << endl;
    getline(cin,filePath); //using getline since a path can have spaces
    cout << "Insert the full file folder path" << endl;
    getline(cin,folderPath);
    if(filePath.find(folderPath) != string::npos)
    {
        cout << "yes";
    }
    else
    {
        cout << "yes";
    }
    return 0;
}
user71381
  • 33
  • 6
1

Only from C++17 there std::filesystem API which has such capability.
For earlier C++ version you have to fall back to boost or system specific library.

Sadly std::filesystem::path doesn't have direct method, but this should do the job:

using std::filesystem::path;

path normalized_trimed(const path& p)
{
    auto r = p.lexically_normal();
    if (r.has_filename()) return r;
    return r.parent_path();
}

bool is_subpath_of(const path& base, const path& sub)
{
    auto b = normalized_trimed(base);
    auto s = normalized_trimed(sub).parent_path();
    auto m = std::mismatch(b.begin(), b.end(), 
                           s.begin(), s.end());

    return m.first == b.end();
}

Live demo

Marek R
  • 32,568
  • 6
  • 55
  • 140