概述:根据文件名字符串的后缀(扩展名)判断文件类型。
通用实现
使用 find_last_of(".") 定位最后一个 . 的位置,再截取其后内容与期望后缀比较:
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(".")返回npos,npos+1溢出为 0,会截取整个文件名。 - 文件名为
".conf"或"a.conf.bak"时,行为可能不符合预期。
推荐封装一个带大小写不敏感与边界检查的辅助函数:
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() |
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)时也会把整段当后缀,实际场景需按需取舍。