How to create a folder in the home directory?
Asked Answered
H

2

9

I want to create a directory path = "$HOME/somedir".

I've tried using boost::filesystem::create_directory(path), but it fails - apparently the function doesn't expand system variables.

How can I do it the simplest way?

(note: in my case the string path is constant and I don't know for sure if it contains a variable)

edit: I'm working on Linux (although I'm planning to port my app to Windows in the near future).

Halie answered 3/2, 2011 at 19:57 Comment(1)
You're working on linux or windows?Delsiedelsman
I
21

Use getenv to get environment variables, including HOME. If you don't know for sure if they might be present, you'll have to parse the string looking for them.

You could also use the system shell and echo to let the shell do this for you.

Getenv is portable (from standard C), but using the shell to do this portably will be harder between *nix and Windows. Convention for environment variables differs between *nix and Windows too, but presumably the string is a configuration parameter that can be modified for the given platform.

If you only need to support expanding home directories rather than arbitrary environment variables, you can use the ~ convention and then ~/somedir for your configuration strings:

std::string expand_user(std::string path) {
  if (not path.empty() and path[0] == '~') {
    assert(path.size() == 1 or path[1] == '/');  // or other error handling
    char const* home = getenv("HOME");
    if (home or ((home = getenv("USERPROFILE")))) {
      path.replace(0, 1, home);
    }
    else {
      char const *hdrive = getenv("HOMEDRIVE"),
        *hpath = getenv("HOMEPATH");
      assert(hdrive);  // or other error handling
      assert(hpath);
      path.replace(0, 1, std::string(hdrive) + hpath);
    }
  }
  return path;
}

This behavior is copied from Python's os.path.expanduser, except it only handles the current user. The attempt at being platform agnostic could be improved by checking the target platform rather than blindly trying different environment variables, even though USERPROFILE, HOMEDRIVE, and HOMEPATH are unlikely to be set on Linux.

Immaterialism answered 3/2, 2011 at 20:9 Comment(0)
O
4

Off the top of my head,

namespace fs = boost::filesystem;
fs::create_directory(fs::path(getenv("HOME")));
Ossieossietzky answered 4/2, 2011 at 22:50 Comment(2)
See "in my case the string path is constant and I don't know for sure if it contains a variable". Also, you might want to check getenv's return value in case HOME isn't set – this should be exceedingly rare, but it would be better to abort or otherwise terminate with an error rather than head into undefined land.Immaterialism
Directory $HOME usually already exists so using create_directory is pointless. Apparently you have forgot about sub directory :P.Vinia

© 2022 - 2024 — McMap. All rights reserved.