如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;
};
但这看起来很荒谬。有没有更好的方法在框架内处理这个问题?
答案 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(); //将获得温度