在C++项目开发中,批量处理文件时经常需要根据特定规则筛选文件名,比如筛选出所有日志文件、特定前缀的配置文件等。fnmatch是C标准库中提供的通配符匹配函数,支持常见的通配符规则,能够方便地实现文件名模式匹配需求,不需要开发者自己编写复杂的匹配逻辑。

fnmatch函数基本说明
fnmatch函数定义在<fnmatch.h>头文件中,它的作用是判断一个字符串是否符合指定的通配符模式。函数原型如下:
#include <fnmatch.h> int fnmatch(const char *pattern, const char *string, int flags);
参数说明:
- pattern:通配符模式字符串,支持星号
*、问号?等通配符 - string:需要匹配的字符串,这里通常是文件名
- flags:匹配标志,常用的有
FNM_NOESCAPE(禁用反斜杠转义)、FNM_PATHNAME(把斜杠当作普通字符处理)等
返回值:如果匹配成功返回0,不匹配返回FNM_NOMATCH,出错返回其他非零值。
常见通配符规则
fnmatch支持的通配符规则如下:
| 通配符 | 说明 | 示例 |
|---|---|---|
* | 匹配任意长度的任意字符,包括空字符 | 模式*.txt匹配所有以txt结尾的文件名 |
? | 匹配单个任意字符 | 模式file?.log匹配file1.log、fileA.log等 |
[abc] | 匹配方括号内的任意一个字符 | 模式file[12].txt匹配file1.txt和file2.txt |
[a-z] | 匹配指定范围内的任意一个字符 | 模式log_[a-c].txt匹配log_a.txt、log_b.txt、log_c.txt |
实战:批量文件名通配符过滤
下面通过一个完整的示例,演示如何遍历指定目录下的所有文件,使用fnmatch过滤出符合指定模式的文件名。
示例代码实现
首先包含需要的头文件,然后实现遍历目录和匹配过滤的逻辑:
#include <iostream>
#include <vector>
#include <string>
#include <fnmatch.h>
#include <dirent.h>
#include <cstring>
// 过滤符合模式的文件名
std::vector<std::string> filter_files_by_pattern(const std::string &dir_path, const std::string &pattern) {
std::vector<std::string> matched_files;
DIR *dir = opendir(dir_path.c_str());
if (dir == nullptr) {
std::cerr << "无法打开目录: " << dir_path << std::endl;
return matched_files;
}
struct dirent *entry;
while ((entry = readdir(dir)) != nullptr) {
// 跳过.和..目录项
if (strcmp(entry->d_name, ".") == 0 || strcmp(entry->d_name, "..") == 0) {
continue;
}
// 使用fnmatch进行模式匹配
int ret = fnmatch(pattern.c_str(), entry->d_name, 0);
if (ret == 0) {
matched_files.push_back(entry->d_name);
} else if (ret != FNM_NOMATCH) {
std::cerr << "fnmatch匹配出错" << std::endl;
}
}
closedir(dir);
return matched_files;
}
int main() {
// 指定要遍历的目录,这里使用当前目录
std::string dir_path = ".";
// 指定匹配模式,这里匹配所有以.cpp结尾的文件
std::string pattern = "*.cpp";
std::vector<std::string> result = filter_files_by_pattern(dir_path, pattern);
std::cout << "匹配到的文件名如下:" << std::endl;
for (const auto &filename : result) {
std::cout << filename << std::endl;
}
return 0;
}
代码说明
上述代码首先实现了filter_files_by_pattern函数,该函数接收目录路径和匹配模式作为参数,遍历目录下的所有文件,使用fnmatch函数判断文件名是否符合模式,将符合的文件名存入向量返回。主函数中调用该函数,匹配当前目录下所有以cpp结尾的文件并输出结果。
注意事项
- fnmatch是C标准库函数,在C++中使用时需要包含
<fnmatch.h>头文件,不同平台的实现可能略有差异,但核心功能一致 - 遍历目录使用了
opendir、readdir等POSIX标准函数,在Windows平台下可能需要使用不同的目录遍历接口,或者安装MinGW等环境支持POSIX函数 - 如果文件名包含中文等多字节字符,需要确保编码一致,避免出现匹配错误
- 匹配模式中的反斜杠默认是转义字符,如果需要匹配字面反斜杠,可以设置
FNM_NOESCAPE标志,或者在模式中写两个反斜杠
fnmatch函数适合简单的通配符匹配场景,如果需要更复杂的匹配规则,比如正则表达式匹配,可以考虑使用C++11之后的<regex>标准库。