如何使用std::filesystem::path在C++中规范化文件路径



我正在尝试将路径字符串转换为标准化(整洁(格式,其中任意数量的目录分隔符"\""/"都转换为一个默认的目录分隔符号:

R"(C:\temp\Recordings/test)" -> R"(C:tempRecordingstest)"

代码:

#include <string>
#include <vector>
#include <iostream>
#include <filesystem>
std::string normalizePath(const std::string& messyPath) {
std::filesystem::path path(messyPath);
std::string npath = path.make_preferred().string();
return npath;
}
int main()
{
std::vector<std::string> messyPaths = { R"(C:\temp\Recordings/test)", R"(C://temp\Recordings////test)" };
std::string desiredPath = R"(C:tempRecordingstest)";
for (auto messyPath : messyPaths) {
std::string normalizedPath = normalizePath(messyPath);
if (normalizedPath != desiredPath) {
std::cout << "normalizedPath: " << normalizedPath << " != " << desiredPath << std::endl;
}
}
std::cout << "Press any key to continue.n";
int k;
std::cin >> k;
}

Windows VS2019 x64上的输出:

normalizedPath: C:\temp\Recordingstest != C:tempRecordingstest
normalizedPath: C:\temp\Recordings\\test != C:tempRecordingstest

正在读取std::filepath文档:

A path can be normalized by following this algorithm:
1. If the path is empty, stop (normal form of an empty path is an empty path)
2. Replace each directory-separator (which may consist of multiple slashes) with a single path::preferred_separator.
... 

很好,但是哪个库函数能做到这一点?我不想自己编写代码。

由bolov回答:

std::string normalizePath(const std::string& messyPath) {
std::filesystem::path path(messyPath);
std::filesystem::path canonicalPath = std::filesystem::weakly_canonical(path);
std::string npath = canonicalPath.make_preferred().string();
return npath;
}

如果路径不存在,weakly_canonical不会引发异常。canonical确实如此。

使用std::filesystem::lexically_normal()。这只执行词法操作,与weakly_canonical不同,它不查询文件系统中的现有路径元素,也不尝试解析符号链接。

std::string normalizePath(const std::string& messyPath) {
return messyPath.lexically_normal();
}

最新更新