【问题标题】:How to filter out the result to get only file names in output result linux in c++98如何过滤出结果以仅获取输出结果中的文件名linux在c ++ 98中
【发布时间】:2021-04-24 03:37:58
【问题描述】:

当前代码 sn-p 将匹配模式并列出所有匹配模式文件存在于指定目录中,下面的示例 文件 是要匹配的模式* ,这里的输出将列出如下的绝对路径。

    /home/downloads/File1
    /home/downloads/File2
    /home/downloads/File3
    /home/downloads/File4

其中,我只查找要列出的文件名,即如下所示:

File1
File2
File3
File4

c++代码如下:

    #include <glob.h>
    #include <cerrno>
    #include <cstring>
    #include <iostream>
    #include <stdexcept>
    #include <string>
    #include <vector>
    using namespace std;
    vector<string> glob(const string& pattern) {
        glob_t glob_result = {0}; // zero initialize
        // do the glob operation
        int return_value = ::glob(pattern.c_str(), GLOB_TILDE, NULL, &glob_result);
        if(return_value != 0) throw runtime_error(strerror(errno));
        // collect all the filenames into a std::vector<std::string>
        // using the vector constructor that takes two iterators
        vector<string> filenames(
            glob_result.gl_pathv, glob_result.gl_pathv + glob_result.gl_pathc);
        // cleanup
        globfree(&glob_result);
        
        // done
        return filenames;
    }
    int main() {
        try { // catch exceptions
               vector<string> res = glob("/home/downloads/File*"); // files with an "File" in the filename
               for(size_t i = 0; i< res.size(); ++i)
                  std::cout << res[i] << '\n';
            } catch(const exception& ex) {
            cerr << ex.what() << endl;
        }
    }

 

【问题讨论】:

    标签: c++ linux string vector absolute-path


    【解决方案1】:

    有点,您可以过滤掉目录。将GLOB_TILDE 更改为GLOB_TILDE | GLOB_MARK,如下所示:

    vector<string> glob(const string& pattern) {
        glob_t glob_result = {};
        vector<string> filenames;
        try {
            int return_value = ::glob(pattern.c_str(), GLOB_TILDE | GLOB_MARK, NULL, &glob_result);
            if (return_value != 0) {
                throw runtime_error(strerror(errno));
            }
            filenames.reserve(glob_result.gl_pathc);
            for (size_t globIndex = 0; globIndex < glob_result.gl_pathc; ++globIndex) {
                std::string filename = glob_result.gl_pathv[globIndex];
                if (filename.size() > 0 && filename[filename.size() - 1] != '/') {
                    filenames.push_back(filename);
                }
            }
        } catch(...) {
            globfree(&glob_result);
            throw;
        }
        // cleanup
        globfree(&glob_result);
    
        // done
        filenames.shrink_to_fit();
        return filenames;
    }
    

    注意事项:

    • 您仍然需要stat 每个结果并检查它是否是一个文件。可以是符号链接、设备文件、命名管道 (FIFO)...
    • 代码不是异常安全的,在填充向量时内存可能会耗尽并且您的清理工作不会发生。使用 try/catch 或 scope_exit 之类的东西(如果可以的话)或编写一个保护对象并使用它的析构函数。
    • 如果出现错误,我不确定您是否应该 globfree,但 valgrind 建议这不是问题。

    【讨论】:

      猜你喜欢
      • 2014-05-14
      • 1970-01-01
      • 1970-01-01
      • 2022-10-23
      • 1970-01-01
      • 1970-01-01
      • 2014-03-06
      相关资源
      最近更新 更多