2

I want to create a file in the path "~/testUsr" while I don't know which "testUsr" exactly is. if I just use path "~/testUsr", it will generate a directory "~" in current path instead of "home/testUsr";

// create directories
    std::string directoryPath = "~/testUsr";
    if(!boost::filesystem::exists(directoryPath)){
        boost::filesystem::create_directories(boost::filesystem::path(directoryPath));
    }

    std::string filePath = directoryPath + "/" + filename +".ini";

    if(!boost::filesystem::exists(filePath)){
        boost::filesystem::ofstream File(filePath) ;
        config.WriteConfigFile(filePath);
        File.close();
    }
    
xinxin wan
  • 23
  • 3
  • You can't use `~` since that is resolved by the shell. [Get home directory in Linux](https://stackoverflow.com/questions/2910377/get-home-directory-in-linux) has some methods you can use to get the home directory. – Retired Ninja Jul 11 '22 at 03:14
  • Do you have to use C++11 or older? Since C++17 there is https://en.cppreference.com/w/cpp/filesystem and you could use that. – Pepijn Kramer Jul 11 '22 at 03:33
  • `~/testUsr` is not a valid path. If you want `~` to refer to home folder then you'll need to manually parse input string and substitute leading `~` with path to home folder, like [bash does](https://www.gnu.org/software/bash/manual/html_node/Tilde-Expansion.html). – user7860670 Jul 11 '22 at 06:56

1 Answers1

1

Using a helper function from Getting absolute path in boost

Live On Coliru

#include <boost/filesystem.hpp>
#include <boost/filesystem/fstream.hpp>
#include <iostream>

using boost::filesystem::path;

struct {
    void WriteConfigFile(std::ostream& os) const {
        os << "[section]\nkey=value\n";
    }
} static config;

path expand(path p) {
    char const* const home = getenv("HOME");
    if (home == nullptr)
        return p; // TODO handle as error?

    auto s = p.generic_string<std::string>();
    if (!s.empty() && s.find("~/") == 0u) {
        return home + s.substr(1);
    }
    return p;
}

int main() {
    path filename = "abc";

    // create directories
    path directoryPath = expand("~/testUsr");
    if (!exists(directoryPath)) {
        create_directories(directoryPath);
    }

    path filePath = directoryPath / filename.replace_extension(".ini");

    if (!exists(filePath)) {
        boost::filesystem::ofstream os(filePath);
        config.WriteConfigFile(os);
    } // os.close(); implied by destructor
}

Note the use of path instead of string to make the code more reliable.

sehe
  • 374,641
  • 47
  • 450
  • 633