如何不通过临时std::string转换获取std::filesystem::path相对路径?
问题
需要从给定基准路径而非根路径获取目标路径的相对路径,即通过std::filesystem::path对象计算两个路径的差异。例如:
std::filesystem::path path = "/var/log", file = "/var/log/folder1/folder2/log.log";
原本期望有operator-运算符实现该功能,示例如下:
std::filesystem::path rel = file - path; // 预期结果为"folder1/folder2/log.log"
目前已通过std::mismatch实现需求,但用到了临时std::string转换,代码如下:
#include <filesystem> #include <iostream> #include <algorithm> int main() { std::filesystem::path path, file; path = "/var/log"; file = "/var/log/folder1/folder2/log.log"; // 临时string转换 std::string path_str = path.string(), file_str = file.string(); std::filesystem::path str = std::string(std::mismatch(file_str.begin(), file_str.end(), path_str.begin()).first, file_str.end()); std::cout << "Relative path is " << str.relative_path() << std::endl; return 0; }
该代码输出:Relative path is "folder1/folder2/log.log"
问题:能否不通过临时std::string转换实现相同功能?
解决方案
当然可以,这里提供两种更优雅的实现方式:
方法一:使用标准库原生函数std::filesystem::relative
C++17的std::filesystem已经内置了计算相对路径的函数std::filesystem::relative,无需手动处理字符串或路径元素,直接满足需求:
#include <filesystem> #include <iostream> int main() { std::filesystem::path base = "/var/log"; std::filesystem::path target = "/var/log/folder1/folder2/log.log"; std::filesystem::path rel = std::filesystem::relative(target, base); std::cout << "Relative path is " << rel << std::endl; }
运行后输出folder1/folder2/log.log,完全符合预期,且是标准库实现,兼容性和可靠性更有保障。
方法二:手动遍历路径元素(无字符串转换)
若不想依赖relative函数,可直接遍历std::filesystem::path的元素迭代器,跳过基准路径的匹配元素后拼接剩余部分:
#include <filesystem> #include <iostream> int main() { std::filesystem::path base = "/var/log"; std::filesystem::path target = "/var/log/folder1/folder2/log.log"; std::filesystem::path rel_path; auto base_it = base.begin(); auto target_it = target.begin(); // 跳过完全匹配的路径元素 while (base_it != base.end() && target_it != target.end() && *base_it == *target_it) { ++base_it; ++target_it; } // 拼接剩余的目标路径元素 for (; target_it != target.end(); ++target_it) { rel_path /= *target_it; } std::cout << "Relative path is " << rel_path << std::endl; }
这种方式直接操作path的原生元素,全程无需转换为std::string,逻辑清晰且结果正确。
内容的提问来源于stack exchange,提问作者StormByte
相关产品推荐
相关产品推荐

