2011-02-03 8 views
6

Chcę utworzyć katalog path = "$HOME/somedir".Jak utworzyć folder w katalogu domowym?

Próbowałem za pomocą boost::filesystem::create_directory(path), ale to się nie powiedzie - najwyraźniej funkcja nie rozszerzać zmienne systemowe.

Jak mogę zrobić to najprostszy sposób?

(uwaga: w moim przypadku ciąg path jest stała i nie wiem na pewno, jeśli zawiera ona zmienną)

edit: pracuję na Linuksie (chociaż mam zamiar portu mój aplikacja do systemu Windows w niedalekiej przyszłości).

+2

Pracujesz na Linux lub Windows? – Nawaz

Odpowiedz

14

Zastosowanie getenv uzyskać zmienne środowiskowe, w tym HOME. Jeśli nie wiesz na pewno, czy mogą być obecni, musisz przeanalizować ciąg, szukając ich.

Można również używać powłoki systemowej i echo pozwolić powłoka zrobić to za Ciebie.

getenv jest przenośny (od standardowej C), ale przy użyciu powłoki zrobić to przenośnie będzie trudniej między * nix i Windows. Konwencja dotycząca zmiennych środowiskowych różni się także między * nix i Windows, ale prawdopodobnie ciąg jest parametrem konfiguracyjnym, który można zmodyfikować dla danej platformy.

Jeśli tylko trzeba wspierać rozszerzenie raczej katalogów domowych niż dowolnych zmiennych środowiskowych, można użyć konwencję ~ a następnie ~/somedir dla ciągów konfiguracyjnych:

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; 
} 

Takie zachowanie jest skopiowane z Pythona os.path.expanduser, oprócz tego, że obsługuje tylko bieżącego użytkownika. Próba bycia agnostykiem platformy może zostać ulepszona poprzez sprawdzenie platformy docelowej, a nie na ślepo próbowanie różnych zmiennych środowiskowych, chociaż prawdopodobnie nie zostaną ustawione na Linuksie.

4

Off szczycie mojej głowy,

namespace fs = boost::filesystem; 
fs::create_directory(fs::path(getenv("HOME"))); 
+1

Zobacz "w moim przypadku ścieżka łańcuchowa jest stała i nie wiem na pewno, czy zawiera zmienną". Możesz również sprawdzić wartość zwracaną przez getenv, na wypadek gdyby nie ustawiono HOME - powinno to być wyjątkowo rzadkie, ale lepiej byłoby przerwać lub w inny sposób zakończyć błąd, zamiast popłynąć w nieokreśloną krainę. –