C++怎么获取文件后缀名 C++ filesystem提取扩展名方法【文件】

1次阅读

c++17起推荐用std::Filesystem::path::extension()提取扩展名,它自动处理路径标准化和边界识别,返回最末段扩展(如”.gz”),需调用.String()转换;对”.tar.gz”等需业务逻辑判断,不支持自动识别多级扩展。

C++怎么获取文件后缀名 C++ filesystem提取扩展名方法【文件】

std::filesystem::path::extension() 直接提取扩展名

这是 C++17 起最标准、最可靠的方式,不需要手动字符串切分或正则匹配。std::filesystem::path 会自动识别合法的扩展名边界(比如处理 .tar.gz 这类多级扩展时,extension() 默认只返回最末段,而 stem()filename() 配合可进一步拆解)。

注意:返回值是 std::filesystem::path 类型,不是 std::string,需调用 .string().u8string() 转换。

  • 若路径为 "report.pdf"p.extension().string()".pdf"
  • 若路径为 "archive.tar.gz",默认返回 ".gz"(不是 ".tar.gz"
  • 若路径无扩展名(如 "README""./config"),返回空 path.string() 为空字符串
  • 路径含非法字符或根本不是文件(只是字符串),extension() 仍能工作——它只解析路径字面量,不访问文件系统

想拿完整扩展(如 .tar.gz)得用 replace_filename() + stem()

extension() 的设计本意就是“最后一段点号之后的部分”,所以它不负责识别复合扩展。真要提取 .tar.gz,得靠人工判断或额外逻辑,常见做法是先去掉主扩展,再对剩余部分重复试探:

std::filesystem::path p = "data.tar.gz"; std::string base = p.stem().string(); // "data.tar" std::string ext1 = p.extension().string(); // ".gz" if (ext1 == ".gz" || ext1 == ".bz2" || ext1 == ".xz") {     auto prev = std::filesystem::path(base).extension();     if (prev == ".tar") {         ext1 = ".tar" + ext1; // ".tar.gz"     } }

这种逻辑必须基于你明确知道的归档组合列表,没有通用银弹。别指望 filesystem 自动识别所有多级扩展。

立即学习C++免费学习笔记(深入)”;

windows 下路径带盘符或反斜杠不影响 extension()

std::filesystem::path 内部会标准化分隔符,无论输入是 "C:\dir\file.txt""C:/dir/file.txt" 还是 "/home/user/file.txt"extension() 行为完全一致。

  • 传入 "C:\log\app.v2.log" → 返回 ".log"
  • 传入 "D:/src/CMakeLists.txt" → 返回 ".txt"
  • 但注意:如果路径以点开头且无其他点(如 ".gitignore"),extension() 会返回 ".gitignore"(整串当扩展),因为 stem() 为空 —— 这是符合 POSIX 路径语义的设计,不是 bug

不用 filesystem 时,手撕字符串容易出错

有人用 find_last_of('.') + substr(),但这在以下情况全军覆没:

  • 路径含目录名带点:如 "./v1.2.3/build/app.exe" → 错误截出 ".3/build/app.exe"
  • 文件名以点开头:如 ".env" → 应该是 ".env",但 naive 实现可能返回空或错截
  • 路径含查询参数或哈希(虽少见):如 "script.js?v=1.0.2" → 点在 URL 部分,不该算扩展
  • 跨平台换行或宽字符未处理:std::string 方案对 UTF-8 路径基本可用,但遇到 windowswchar_t 路径就失效

除非项目卡在 C++11/C++14 且无法引入 filesystem(此时建议用 Boost.Filesystem),否则别自己解析路径字符串。

真正麻烦的是复合扩展和隐藏文件的语义区分,这些不在 filesystem 职责范围内,得由业务层定义规则。

text=ZqhQzanResources