0

Supposing that I have the following structure:

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

  • we know that in Folder there's only one .suffix subdirectory but we only know for sure its prefix ( the name may differ ).
  • how can I get to wanted_file.txt ?

I've tried something like:

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

It doesn't work this way (it prints 6-7 random chars).

The finalpath is being printed with cout if I remove \\*.prefix\\wanted_file.txt from the whole path, so I suppose the syntax that I've tried it's just not good.

I'd like, if possible, a solution that doesn't involve require boost.

Cajuu'
  • 1,154
  • 2
  • 19
  • 50
  • On an unrelated note, the terminology here seems a little off, a "prefix" is something that is put *before*, and a "suffix" is something that is put *after*. – Some programmer dude Sep 23 '15 at 09:42
  • It's just a typo, will make the changes – Cajuu' Sep 23 '15 at 09:43
  • 2
    If you're limiting yourself to Windows which seems likely from the question, you can use FindFirstFile and friends which accepts wildcards. Or even just use FindFirstFile with "C:\Users\User\AppData\Folder\\*" to get the name of the directory. – Mike Vine Sep 23 '15 at 09:44
  • I'm gonna try that out @MikeVine – Cajuu' Sep 23 '15 at 09:47
  • @MikeVine , could you please improve your comment in an answer ? `FindFirstFile` might do its job but I can't get it work as it includes `windows.h` and I have to convert everything. – Cajuu' Sep 23 '15 at 10:03
  • [Boost](http://www.boost.org/) contains a platform-independent filesystem library that can iterate files and directories. It might be an alternative to pulling in the WINAPI just for filesystem operations. – Steve Sep 23 '15 at 12:14

2 Answers2

1

Just iterate through the folder and find the the one with the suffix, examples for iterating:

My favorite approach is with the tinydir single-header library, because it's simple and portable. Here's how you get the name of the folder that ends with the suffix (requires C++11 for std::move, you can just get rid of it):

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;
}
Community
  • 1
  • 1
ProGTX
  • 11
  • 3
0

If your environment supports the Filesystem TS (ISO/IEC TS 18822:2015) extension, the functionality of Boost.Filesystem is provided by 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;
}

This is supported, I am told, by MSVC 2012 and Clang 3.5, with GCC 5.3 catching up later in 2015.

Later versions will probably include <filesystem> (without the "experimental"), making this the future-compatible solution.

Community
  • 1
  • 1
DevSolar
  • 67,862
  • 21
  • 134
  • 209
  • @Alexander: Missed your "no Boost" requirement at first take. Fair enough. (Although I consider it a dubious and artificially crippling requirement.) -- However, Boost.Filesystem made it into the standard by now. ;-) – DevSolar Sep 23 '15 at 12:22