parent_path()带或不带斜杠

时间:2016-04-29 15:14:34

标签: c++ boost boost-filesystem

documentation中所述,以下预期输出为:

parent_path()

问题是,你如何应对这个问题?也就是说,如果我接受一个路径作为参数,我不希望用户关心它是否应该有一个尾部斜杠。看起来最简单的事情就是附加一个尾部斜杠,然后调用boost::filesystem::path filePath1 = "/home/user/"; filePath1 /= "/"; cout << filePath1.parent_path().parent_path() << endl; // outputs "/home" boost::filesystem::path filePath2 = "/home/user"; filePath2 /= "/"; cout << filePath2.parent_path().parent_path() << endl; // outputs "/home" TWICE来获取&#34; / home&#34;的父路径。我想要的:

struct A {

    int get_range() const {
        if (!_repr2) {
            _repr2 = Repr2(*_repr1); 
        }
        return _repr2->get_range();
    }    

private:
    mutable boost::optional<Repr1> _repr1;
    mutable boost::optional<Repr2> _repr2;
};

但这看起来很荒谬。有没有更好的方法在框架内处理这个问题?

4 个答案:

答案 0 :(得分:7)

有一个(未记录的?)成员函数path& path::remove_trailing_separator();

我试过这个,它在Windows上使用boost 1.60.0:

    boost::filesystem::path filePath1 = "/home/user/";
    cout << filePath1.parent_path() << endl; // outputs "/home/user"
    cout << filePath1.remove_trailing_separator().parent_path() << endl; // outputs "/home"

    boost::filesystem::path filePath2 = "/home/user";
    cout << filePath2.parent_path() << endl; // outputs "/home"
    cout << filePath2.remove_trailing_separator().parent_path() << endl; // outputs "/home"

答案 1 :(得分:1)

看起来很像,虽然我建议先使用目录string进行操作,而不是两次调用parent_path()

std::string directory = "/home/user"; // Try with "/home/user/" too, result is the same

while ((directory.back() == '/') || (directory.back() == '\\')))
    directory.erase(directory.size()-1);    

boost::filesystem::path filePath(directory);
std::cout << filePath.parent_path() << std::endl; // outputs "/home" 

值得注意的是std::string::back()是C ++ 11的一项功能。如果您需要使用以前的版本进行编译,则必须稍微更改算法。

答案 2 :(得分:1)

要从目录的路径中删除尾随分隔符,到目前为止这对我有用:

/**
 * Creates lexically normal (removes extra path separators and dots) directory
 * path without trailing path separator slash(es)
 * @param dir_path - directory path to normalize
 */
void normalize_dir_path(boost::filesystem::path& dir_path) {
    // @HACK - append non-existing file to path so that we may later resolve
    // normalized directory path using parent_path()
    dir_path /= "FILE.TXT";
    // Remove unneeded dots and slashes
    dir_path = dir_path.lexically_normal();
    // Remove trailing slash from original path!
    dir_path = dir_path.parent_path();
}

上述答案类似于OP的原始发布解决方法(添加'/')以及Wurmloch关于使用lexically_normal()的评论。一个优点是仅使用boost::filesystem中记录的方法。一个可能的缺点是调用者必须确信输入参数dir_path旨在成为目录而不是常规文件。

使用normalize_dir_path(...)方法回答OP的问题:

boost::filesystem::path filePath1 = "/home/user/";
normalize_dir_path(filePath1); // filePath1 is now "/home/user"
cout << filePath1.parent_path() << endl; // outputs "/home"

boost::filesystem::path filePath2 = "/home/user";
normalize_dir_path(filePath2); // filePath2 is now "/home/user"
cout << filePath2.parent_path() << endl; // outputs "/home"

boost::filesystem::path filePath3 = "/home/user/.";
normalize_dir_path(filePath3); // filePath3 is now "/home/user"
cout << filePath3.parent_path() << endl; // outputs "/home"

<强>更新

刚刚意识到boost::filesystem::path::lexically_normal()仅适用于BOOST版本&gt; = 1_60_0。对于早期版本,默认情况下似乎有一个已弃用的函数boost::filesystem::path::normalize()(只要未定义BOOST_FILESYSTEM_NO_DEPRECATED)。所以,我当前的规范化目录路径方法是这样的:

#include <boost/version.hpp>

void normalize_dir_path(boost::filesystem::path& dir_path) {
    // @HACK - append non-existing file to path so that we may later resolve
    // normalized directory path using parent_path()
    dir_path /= "FILE.TXT";
    // Remove unneeded dots and slashes
#if BOOST_VERSION >= 106000
    dir_path = dir_path.lexically_normal();
#else
    dir_path.normalize();
#endif
    // Remove trailing slash from original path!
    dir_path = dir_path.parent_path();
}

答案 3 :(得分:0)

使用std :: filesystem :: canonical-C ++ 17

  

命名空间fs = std :: filesystem;

     

fs :: path tmp =“ c:\ temp \”;

     

tmp = fs :: canonical(tmp); //将删除斜杠

     

fs :: path目录名= tmp.filename(); //将获得温度