I am trying to convert a path string to a normalized (neat) format where any number of directory separators "\\" or "/" is converted to one default directory separator:
R"(C:\\temp\\Recordings/test)" -> R"(C:\temp\Recordings\test)"
Code:
#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:\temp\Recordings\test)";
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;
}
Output on Windows VS2019 x64:
normalizedPath: C:\\temp\\Recordings\test != C:\temp\Recordings\test
normalizedPath: C:\\temp\\Recordings\\\\test != C:\temp\Recordings\test
Reading the std::filepath documentation:
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.
...
Great, but which library function does this? I do not want to code this myself.
As answered by 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 does not throw an exception if path does not exist.
canonical does.
Use std::filesystem::lexically_normal(). This performs a lexical operation only, and unlike weakly_canonical it does not query the filesystem for existing path elements, and makes no attempt to resolve symbolic links.
std::string normalizePath(const std::string& messyPath) {
return messyPath.lexically_normal();
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With