首页 > 解决方案 > 如何使用 C++17 的文件系统检查路径是否引用 Windows 中的卷?

问题描述

我在 Windows 上使用 C++17。据我所知,std::filesystem没有is_root()函数或类似的东西告诉我路径是否直接指向 C: 或 D: 或任何其他卷。我错过了什么吗?

目前我正在这样做:

if (path.parent_path() == path)
{
    //
}

看起来它正在工作,但我不知道这是否遗漏了任何边缘情况。有没有更好的办法?

编辑:

我想检查整个路径是否只是卷名(可能后跟可选的斜杠或反斜杠)。

所以,如果有这样的函数,我希望它的行为如下:

namespace fs = std::filesystem;
is_root(fs::path{ "C:" }); // true
is_root(fs::path{ "D:\\"}); // true
is_root(fs::path{ "C:/users" }) // false
is_root(fs::current_path()) // usually false, unless the executable was started directly in C: or D: or any other drive

标签: c++windowsfilesystemsc++17

解决方案


首先,检查是否它has_root_name();没有一个,它显然没有指定一个卷。

困难的部分是弄清楚它是否只有一个根名称。这很复杂,因为如果指定了路径,您还想忽略路径的根目录。

迭代器范围是一个很好的、性能友好的解决方案。如果它有根名称,则begin()指向该根名称。所以如果你增加它,它会指向路径中的下一个组件。

如果路径同时具有根名称和根目录,则根名称之后的组件就是根目录。因此,如果您递增超过则迭代器要么指向一个附加组件,要么已达到end范围的 。如果它在end,那么什么都没有了,你知道路径“只是一个卷”。

代码如下所示:

bool is_volume(const fs::path &p)
{
  if(!p.has_root_name()) return false;

  auto it = p.begin();
  ++it; //Skip the root-name

  if(p.has_root_directory())
    ++it; //Skip the root-directory.

  if(it == p.end())
    return true;

  return false;
}

推荐阅读