4

这个程序:

#include <iostream>
#include <filesystem>

int main()
{
    std::filesystem::path p1("c:\\");
    std::filesystem::path p2("c:/");
    if (p1.has_parent_path())
        std::cout << "Parent path of " << p1 << " is " << p1.parent_path() << std::endl;
    if (p2.has_parent_path())
        std::cout << "Parent path of " << p2 << " is " << p2.parent_path() << std::endl;
}

产生这个输出:

Parent path of "c:\\" is "c:\\"
Parent path of "c:/" is "c:/"

编辑:我对正斜杠的使用感到困惑,所以我更新了这段代码以显示无论您在 Windows 上使用哪种路径分隔符都会发生同样的事情)

这对我来说毫无意义。目录如何成为其自身的父级?如果它永远不会返回 false,那么即使有一个“has_parent”函数又有什么意义呢?

最重要的是:如果我正在编写递归搜索目录树以查找文件的代码,那么检测我已经点击根文件夹并应该停止的最佳/最可靠的方法是什么?

(如果重要的话,我在 C++17 语言模式下使用 Visual Studio 2019)

4

2 回答 2

3

实际上godbolt示例中没有输出,因为测试是在posix环境下的GCC上运行的,其中"C:\\"不是根目录,所以它被视为一个奇怪的目录/文件名,其父级为空,但正确 "/"正如 OP 所观察的那样,它会给出输出的posix 根路径。所以不,根目录("/""C:\\")的 parent_path() 不为空,所以 has_parent_path() 在我知道的所有 std::filesystem 实现上都是正确的。

实际标准说:“返回:*thisif has_relative_path()is false,否则一条路径,其通用格式路径名是通用格式路径名的最长前缀,*this在其迭代中产生更少的元素。” andrelative_path()是 之后的所有内容root_path(),因此relative_path()在这种情况下没有,因此parent_path()返回*thishas_parent_path()返回 true,如 OP 示例中所示。

我对标准为什么选择这种行为的问题的猜测是,这就是cd ..每个操作系统上所做的事情,如果你已经在根目录,那么你就留在同一个根目录。

确实,检测结束的一种可能方法是:(!p.has_parent_path() || !p.has_relative_path())或者甚至可能!p.has_relative_path(),这取决于如果它是无根的,是否要以空路径结束。

于 2019-10-04T10:33:21.520 回答
0

函数bool has_parent_path() const;检查函数返回的路径是否path parent_path() const;为空。

此外,对于path parent_path() const;功能,标准说:

返回通用格式路径的根目录。如果路径(通用格式)不包括根目录,则返回 path()。

在根路径为 的 Linux 系统上,以及根路径为/的 Windows 系统上C:\\parent_path()函数将返回空字符串,因此,has_parent_path()函数将返回 false。

从这里检查此代码:

#include <iostream>
#include <experimental/filesystem>

namespace fs = std::experimental::filesystem;

int main() {
    for (fs::path p : {"/var/tmp/example.txt", "/", "C:\\", "/var/tmp/."}) {
        std::cout << "The parent path of " << p
                  << " is " << p.parent_path() << '\n';
        std::cout << "Has parent path: " << p.has_parent_path() << '\n';
    }

    return 0;
}

注意拼写Windows根目录。不是c:/但是C:\\

于 2019-10-02T12:26:15.613 回答