C++基于std::filesystem实现.kbin后缀目录检索的编译报错问题
编译错误成因与修复
各错误对应成因
directory_entry无substr/find_last_of成员类错误
代码中误将fs::recursive_directory_iterator遍历得到的std::filesystem::directory_entry类型对象,直接当做普通字符串调用字符串类的substr、find_last_of方法。实际上directory_entry是对目录项的封装类,本身不提供任何字符串操作接口,自然找不到对应成员方法;同时书写时还把substr笔误成了subentry,进一步放大了类型不匹配的问题。一元&操作数要求为左值错误
代码中&files->push_back(entry.path())属于多余操作:std::vector::push_back是无返回值的成员函数,本身没有可被取地址的实体,强行在调用前加取地址符&,编译器自然会报操作数类型不匹配的错误。- 额外的潜在参数不匹配问题:
定义的GetListOfFiles函数形参是std::vector<std::string>*指针类型,但在main函数中调用时直接传入了栈上的filesvector对象,没有对其取地址,就算前面的错误全部修复,也会触发函数参数类型不匹配的编译错误。
修复方案
- 路径后缀判断不要手动解析字符串,直接使用
std::filesystem::path自带的extension()方法获取文件后缀,该方法会返回带前置点的后缀字符串(比如test.kbin会返回.kbin),直接和目标后缀比较即可,不需要手动定位最后一个.的位置。 - 去掉
push_back调用前多余的取地址符,直接正常调用成员方法即可。 - 统一函数传参逻辑:将形参改成引用传递(比指针更安全易用),避免指针传参带来的空指针、传参不匹配问题。
修复后可正常编译运行的示例代码
#include <string> #include <iostream> #include <vector> #include <filesystem> namespace fs = std::filesystem; // 形参改为const引用和普通引用,消除指针传参的隐患 void GetListOfFiles(const std::string& path, std::vector<std::string>& files) { // 遍历时跳过无权限的目录,避免程序抛异常退出 for (const auto& entry : fs::recursive_directory_iterator( path, fs::directory_options::skip_permission_denied )) { // 仅匹配普通文件的.kbin后缀,跳过目录、符号链接等特殊项 if (entry.is_regular_file() && entry.path().extension() == ".kbin") { // 去掉多余的&,将路径转为字符串存入vector files.push_back(entry.path().string()); } } } int main(int argc, char** argv) { if (argc < 2) { std::cerr << "Usage: " << argv[0] << " <target_directory>\n"; return 1; } std::string path = argv[1]; std::vector<std::string> files; GetListOfFiles(path, files); // 打印匹配结果做验证 for (const auto& f : files) { std::cout << f << '\n'; } return 0; }
编译命令说明
g++ 9.3.0 环境下C++17的filesystem库仍需要额外链接,原编译命令可直接正常使用:g++ main.cpp -o main -lstdc++fs -std=c++17
内容的提问来源于stack exchange,提问作者Bogfoot
相关产品推荐
相关产品推荐

