【问题标题】:How does one access a file from subdirectory that contains specific termination?如何从包含特定终止的子目录访问文件?
【发布时间】:2015-12-20 13:28:25
【问题描述】:

假设我有以下结构:

C:\Users\User\AppData\Folder\subfolder.suffix\wanted_file.txt

  • 我们知道Folder 中只有一个.suffix 子目录,但我们只能确定它的前缀(名称可能不同)。
  • 我怎样才能到达wanted_file.txt

我尝试过类似的方法:

std::string halfpath = getenv("APPDATA");
std::string anotherhalfpath = "\\Folder\\*.suffix\\wanted_file.txt";
std::string finalpath = halfpath + anotherhalfpath;

这种方式不起作用(它会打印 6-7 个随机字符)。

如果我从整个路径中删除\\*.prefix\\wanted_file.txtfinalpath 将与cout 一起打印,所以我认为我尝试过的语法并不好。

如果可能的话,我想要一个不涉及 require boost 的解决方案。

【问题讨论】:

  • 在一个不相关的注释中,这里的术语似乎有点不对劲,“前缀”是放在 之前的东西,而“后缀”是放在 之后.
  • 这只是一个错字,将进行更改
  • 如果您将自己限制在 Windows 上,这似乎从问题中可以看出,您可以使用 FindFirstFile 和接受通配符的朋友。或者甚至只是使用带有“C:\Users\User\AppData\Folder\*”的 FindFirstFile 来获取目录的名称。
  • 我要试试@MikeVine
  • @MikeVine,您能否在回答中改进您的评论? FindFirstFile 可能会完成它的工作,但我无法让它工作,因为它包含 windows.h,我必须转换所有内容。

标签: c++


【解决方案1】:

只要遍历文件夹,找到后缀的那个,迭代的例子:

我最喜欢的方法是使用tinydir 单头库,因为它简单且可移植。以下是获取以后缀结尾的文件夹名称的方法(std::move 需要 C++11,你可以去掉它):

std::string getDirWithSuffix(std::string path, std::string suffix) {
    tinydir_dir dir;
    std::string directory("");

    if(tinydir_open(&dir, path.c_str()) == -1) {
        return directory;
    }

    while(dir.has_next) {
        tinydir_file file;
        if(tinydir_readfile(&dir, &file) != -1) {
            if(file.is_dir) {
                std::string dirname(file.name);
                // https://stackoverflow.com/questions/874134/find-if-string-endswith-another-string-in-c
                if(
                    dirname.length() >= suffix.length() &&
                    dirname.compare(dirname.length() - suffix.length(), suffix.length(), suffix) == 0
                ) {
                    directory = std::move(dirname);
                    break;
                }
            }
        }
        tinydir_next(&dir);
    }

    tinydir_close(&dir);
    return directory;
}

【讨论】:

    【解决方案2】:

    如果您的环境支持Filesystem TS (ISO/IEC TS 18822:2015) 扩展,Boost.Filesystem 的功能由std:: 提供。

    #include <experimental/filesystem>
    #include <algorithm>
    
    #include <iostream>
    #include <string>
    
    int main()
    {
        // APPDATA, of course, is *NOT* portable
        std::path path_to_folder( getenv("APPDATA") );
        path_to_folder /= "Folder";
        std::directory_iterator it( path_to_folder );
        std::directory_iterator end;
        std::string suffix=".suffix";
        while ( it != end )
        {
            if ( suffix.length() <= filename.length()
                 &&
                 std::equals( suffix.rbegin(), suffix.rend(), filename.rbegin() )
            {
                std::cout << filename << "\n";
            }
            ++it;
        }
        return 0;
    }
    

    据我所知,MSVC 2012 和 Clang 3.5 支持 GCC 5.3 catching up later in 2015

    以后的版本可能会包含&lt;filesystem&gt;(没有“实验性”),使其成为未来兼容的解决方案。

    【讨论】:

    • @Alexander:一开始就错过了您的“无 Boost”要求。很公平。 (尽管我认为这是一个可疑的、人为的严重要求。)——然而,Boost.Filesystem 现在已经将它变成了标准。 ;-)
    猜你喜欢
    • 2015-02-07
    • 1970-01-01
    • 2013-06-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-01-04
    • 2023-04-01
    • 2017-04-29
    相关资源
    最近更新 更多