为什么路径的迭代器在遍历时返回“ \\”?

时间:2019-07-05 11:19:37

标签: c++ c++17

我正在使用带有文件系统API的新的和现代的C ++ 17。我正在Windows中使用Visual Studio2017。

以下代码给出了意外的结果:

#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中对此进行测试(请在path变量中将“ \”更改为“ /”),结果是:

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

为什么行为不同?

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

1 个答案:

答案 0 :(得分:9)

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

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

  

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

     
      
  • root-name元素(如果存在)。
  •   
  • root-directory元素(如果存在)。 [注意:必须使用通用格式,以确保词典比较正确地进行。 —注释]
  •   
  • 每个连续的filename元素(如果存在)。
  •   
  • 如果存在尾随的非根directory-separator,则为空元素。
  •   

在Windows上,路径D:\dir\file.cpp的磁盘标识符为D:,然后是该磁盘上的根目录\,然后是路径dir,{ {1}}。根据Windows,file.cpp是根名称,因此D:是根目录。您可能有\,但请注意,这现在是相对路径。

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