概述:根据文件名字符串的后缀(扩展名)判断文件类型。

通用实现

使用 find_last_of(".") 定位最后一个 . 的位置,再截取其后内容与期望后缀比较:

C++cpp
#include <iostream>
#include <string>
 
int main()
{
  std::string fn = "filename.conf";
  if(fn.substr(fn.find_last_of(".") + 1) == "conf") {
    std::cout << "Yes..." << std::endl;
  } else {
    std::cout << "No..." << std::endl;
  }
}

该方案完整、可读,适合绝大多数场景。

扩展:更健壮的封装

上面的写法在某些边界情况下可能有问题:

  • 文件名为 "file"(无 .)时,find_last_of(".") 返回 nposnpos+1 溢出为 0,会截取整个文件名。
  • 文件名为 ".conf""a.conf.bak" 时,行为可能不符合预期。

推荐封装一个带大小写不敏感与边界检查的辅助函数:

C++cpp
#include <iostream>
#include <string>
#include <algorithm>
#include <cctype>
 
// 获取小写扩展名,无后缀返回空串
std::string getExtension(const std::string& path)
{
    size_t pos = path.find_last_of(".");
    if (pos == std::string::npos || pos == 0 || pos == path.size() - 1)
        return "";
    std::string ext = path.substr(pos + 1);
    std::transform(ext.begin(), ext.end(), ext.begin(),
        [](unsigned char c) { return std::tolower(c); });
    return ext;
}
 
bool hasExtension(const std::string& path, const std::string& ext)
{
    return getExtension(path) == ext;
}
 
int main()
{
    std::string fn = "filename.CONF";        // 大小写不敏感
    if (hasExtension(fn, "conf")) {
        std::cout << "Yes..." << std::endl;
    } else {
        std::cout << "No..." << std::endl;
    }
}

各种路径方案对比

需处理场景推荐方法
仅判断纯文件名后缀find_last_of(".") 截取
含目录路径且目录名含点find_last_of("/\\") 取文件名再取后缀
大小写不敏感转小写后比较(std::tolower / _stricmp
需要底层系统支持Windows PathFindExtension / Linux filesystem::path::extension()
C++cpp
// C++17 filesystem 一行获取扩展名
#include <filesystem>
std::string ext = std::filesystem::path(fn).extension().string(); // ".conf"

注意std::filesystem::path::extension() 返回带点的后缀(如 ".conf"),与上述手写 "conf" 不同;find_last_of(".") 方案遇到文件名本身以点开头(如 .bashrc)时也会把整段当后缀,实际场景需按需取舍。