首页 > 解决方案 > 为什么路径的迭代器在遍历时返回“\\”?

问题描述

我正在使用带有文件系统 API 的新的现代 C++17。我在 Windows 中使用 Visual Studio 2017 工作。

以下代码给出了意想不到的结果:

#include <iostream>
#include <filesystem>

int main()
{
  std::filesystem::path path(R"(D:\dir\file.cpp)");
  for (auto& dir : path)
  {
    std::cout<<dir<<std::endl;
  }
}

结果是:

"D:"
"\\"
"dir"
"file.cpp"

为什么要打印“\\”?

在 GCC 9.1.0 中对此进行测试(请将路径变量中的 '\' 更改为 '/'),结果为:

"D:"
"dir"
"file.cpp"

为什么行为不同?

根据 C++17 标准,哪个结果是正确的?

标签: c++c++17

解决方案


有关 Windows 路径名的一些信息,请参阅https://docs.microsoft.com/en-us/windows/win32/fileio/naming-a-file#fully-qualified-vs-relative-paths

C++ 标准对路径迭代器([fs.path.itr]/4)有这样的说法:

对于通用格式的路径名的元素,前向遍历顺序如下:

  • 名称元素(如果存在)。
  • 目录元素(如果存在)。[注意:需要通用格式以确保词典比较正常工作。——尾注]
  • 每个连续的文件名元素(如果存在)。
  • 如果存在尾随非根目录分隔符,则为空元素。

在 Windows 上,路径D:\dir\file.cpp有一个磁盘指示符D:,后跟该磁盘上的根目录,\,然后是路径dirfile.cpp。根据windows,D:是一个根名称,所以\是一个根目录。你可以有D:dir\file.cpp,但请注意,这现在是一个相对路径。

在 gcc 上,如果不在 windows 上,D:将被视为常规目录名称(与 相同./D:/dir/file.cpp)。因此,没有根名称或根目录。如果您有/D:/dir/file.cpp,则迭代器将包含/, D:, dir, file.cpp


推荐阅读