我正在使用带有文件系统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标准,哪个结果正确?
答案 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
。