10

This is a complimentary question to:
How to build a full path string (safely) from separate strings?

So my question, how to split a path into separate strings in a cross platform manner.

This solution, using Boost.Filesystem is very elegant and Boost must have implemented some splitPath() function. I couldn't find any.

Note: bear in mind that I can do this task myself but I'm more interested in a closed box solution.

Community
  • 1
  • 1
idanshmu
  • 5,061
  • 6
  • 46
  • 92

4 Answers4

15

Indeed, there is path_iterator. But if you want elegance:

#include <boost/filesystem.hpp>

int main() {
    for(auto& part : boost::filesystem::path("/tmp/foo.txt"))
        std::cout << part << "\n";
}

Prints:

"/"
"tmp"
"foo.txt"

And

    for(auto& part : boost::filesystem::path("/tmp/foo.txt"))
        std::cout << part.c_str() << "\n";

prints

/
tmp
foo.txt

No need to worry about the moving parts

sehe
  • 374,641
  • 47
  • 450
  • 633
5
std::vector<std::string> SplitPath(const boost::filesystem::path &src) {
    std::vector<std::string> elements;
    for (const auto &p : src) {
        elements.emplace_back(p.filename());
    }
    return elements;
}
ALittleDiff
  • 1,191
  • 1
  • 7
  • 24
1

If you don't have C++11 auto, or are writing cross-platform code where boost::filesystem::path might be std::wstring:

std::vector<boost::filesystem::path> elements;
for (boost::filesystem::path::iterator it(filename.begin()), it_end(filename.end()); it != it_end; ++it) 
{
    elements.push_back(it->filename());
}
Jason Harrison
  • 922
  • 9
  • 27
1

If you want to do everything manually without, using any library, then this will help. It splits the given full path into corresponding names and store them in a vector.

#include <iostream>
#include <string>
#include <vector>
using namespace std;

int main()
{
    string filePath = "C:\\ProgramData\\Users\\CodeUncode\\Documents";
    vector<string> directories;
    size_t position=0, currentPosition=0;
    
    while(currentPosition != -1)
    {
        currentPosition = filePath.find_first_of('\\', position);
        directories.push_back(filePath.substr(position,currentPosition-position));
        position = currentPosition+1;
    }
    for(vector<string>::iterator it = directories.begin(); it!=directories.end(); it++)
        cout<<*it<<endl;

    return 0;
} 

Output:

C:
ProgramData
Users
CodeUncode
Documents
  • You have posted the same (poor) code [here](https://stackoverflow.com/a/69426192/10871073). Best not to post 'duplicate' answers to multiple questions ... consider deleting one answer and improving the other. – Adrian Mole Oct 03 '21 at 15:38