You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

带末尾斜杠与不带斜杠的路径调用parent_path结果不同,此行为是否合规?

std::filesystem::path parent_path() 行为疑问

问题场景

假设路径/tmp/test/t的父路径应为/tmp/test,带尾部斜杠的/tmp/test/t/预期父路径也为/tmp/test,但使用C17的std::filesystem::path调用parent_path()时,两者结果不一致:前者返回/tmp/test,后者返回/tmp/test/t,导致断言失败。编译环境为Ubuntu 22.04下的g 11.4.0,编译命令为g++ -std=c++17 main.cpp -o main。

代码示例:

#include <filesystem>
#include <iostream>
#include <string>
#include <cassert>

int main(void) {

    auto parent_one = std::filesystem::path("/tmp/test/t/").parent_path();
    auto parent_two = std::filesystem::path("/tmp/test/t").parent_path();

    std::cout << parent_one << "\n";
    std::cout << parent_two << "\n";

    assert(parent_one == parent_two); 
}

解答

这是符合C++标准规定的正确行为,原因在于std::filesystem::path对路径的解析规则:

  • 带尾部斜杠的路径(如/tmp/test/t/)会被解析为包含一个末尾空元素的路径结构(斜杠作为分隔符,尾部斜杠相当于在最后添加了一个空元素);
  • parent_path()的作用是移除路径结构中的最后一个元素,因此对于带尾部斜杠的路径,移除末尾的空元素后,得到的是/tmp/test/t;而不带尾部斜杠的/tmp/test/t,最后一个元素是t,移除后得到/tmp/test。

如果需要让两种格式的路径返回一致的父路径,可以先调用lexically_normal()标准化路径,该函数会自动移除尾部冗余的斜杠(以及其他冗余路径部分如./、../),示例修改如下:

#include <filesystem>
#include <iostream>
#include <string>
#include <cassert>

int main(void) {
    auto path1 = std::filesystem::path("/tmp/test/t/").lexically_normal();
    auto parent_one = path1.parent_path();
    auto path2 = std::filesystem::path("/tmp/test/t").lexically_normal();
    auto parent_two = path2.parent_path();

    std::cout << parent_one << "\n";
    std::cout << parent_two << "\n";

    assert(parent_one == parent_two); // 此时断言会通过
}

内容的提问来源于stack exchange,提问作者Lars Kakavandi-Nielsen

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.24 01:03:11