Search code examples
c++boostboost-filesystem

What is the right way to add secondary extension to boost::filesystem::path?


I want to append additional extension to a path:

namespace fs = boost::filesystem;
fs::path append_extension(const fs::path& path, const fs::path& ext);

Expected behavior:

  • append_extension("foo.txt", ".log") -> "foo.txt.log"
  • append_extension("foo.txt", "log") -> "foo.txt.log"
  • append_extension("foo", "log") -> "foo.log"

Is it possible to implement append_extension without string manipulations with dot character?


Solution

  • How about

    namespace fs = boost::filesystem;
    fs::path append_extension(const fs::path& path, const fs::path& ext) {
        auto sz_ext = ext.c_str();
        if ('.' == *sz_ext) ++sz_ext;
        return path.string<std::string>() + "." + sz_ext;
    }
    

    Is it possible to implement append_extension without string manipulations with dot character?

    No. Extensions aren't a thing, they're merely conventions. Secondary extensions aren't even a convention, so you're on your own.

    DEMO

    Live On Coliru

    #include <boost/filesystem.hpp>
    #include <boost/property_tree/string_path.hpp>
    
    namespace fs = boost::filesystem;
    fs::path append_extension(const fs::path& path, const fs::path& ext) {
        auto sz_ext = ext.c_str();
        if ('.' == *sz_ext) ++sz_ext;
        return path.string<std::string>() + "." + sz_ext;
    }
    #include <iostream>
    
    int main() {
        std::cout << append_extension("foo.txt", ".log") << "\n"; // -> "foo.txt.log"
        std::cout << append_extension("foo.txt", "log") << "\n"; // -> "foo.txt.log"
        std::cout << append_extension("foo", "log") << "\n"; // -> "foo.log"
    }
    

    Prints

    "foo.txt.log"
    "foo.txt.log"
    "foo.log"