how to get a file name with a part of the file name?

I want list all the files with the same substring as a name?
for example there are 10 files with same substring as "testoutput" I want list all of them. How can I do that?
You do have two logical subtasks:
1. Get a list of filenames from the filesystem.
2. Select from list entries that contain the substring. string::contains()
Which o/s are you talking about?

There is no standard, generic C++ or C way do to this yet.

You could use Boost.FileSystem (the directory_iterator) -- this will very likely be part of a future version of C++ (it's been accepted for Technical Review 2)
http://www.boost.org/doc/libs/1_53_0/libs/filesystem/doc/index.htm

Or you will need to use your o/s file systems calls directly.

- For Linux you have to use the POSIX opendir, readdir, closedir which allow you to get all files. It is then up to you to filter the results based on your substring.

- With Win32 it's a little different to what keskiverto says: the FindFirstFile call (corresponding to opendir) can be used with wild card, so you should be able to get the filtered set of files directly. The calls required are FindFirstFile, FindNextFile, FindClose

(There are also corresponding Microsoft CRT calls -- _findfirst, _findnext, and _findclose -- but I've never seen them used.)

Andy
Last edited on
If one does use Qt, then one can write semi-portable code (because Qt hides the OS-specifics inside its implementation.
Last edited on
If we're talking about cross-platform GUI frameworks that provide directory enumeration, then we've also got wxWidgets (wxDir::GetFirst, wxDir::GetNext, wxDir::Traverse) as well as Qt.

(Of course MFC provides one, too; but it's just a class wrapper for the Win32 calls. And it's not cross-platform.)

Andy

Last edited on
Boost example:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
#include <vector>
#include <string>
#include <iostream>

#include <boost/filesystem.hpp>

std::vector<std::string> getFileNames(std::string path = ".") ;
void filter(std::vector<std::string>& strings, std::string pattern) ;
void print(const std::vector<std::string> & v) ;

int main()
{
    auto names = getFileNames() ;
    filter(names, "test") ;

    std::cout << "Files containing \"test\" in the current directory:\n" ;
    print(names) ;
}

std::vector<std::string> getFileNames(std::string directoryPath)
{
    namespace fs = boost::filesystem ;
    std::vector<std::string> names ;

    if ( fs::exists(directoryPath) )
    {
        fs::directory_iterator it(directoryPath) ;
        fs::directory_iterator end ;

        while ( it != end )
        {
            names.push_back(it->path().filename().string()) ;
            ++it ;
        }
    }

    return names ;
}

void filter(std::vector<std::string>& strings, std::string pattern)
{
    auto pos = std::remove_if(std::begin(strings), std::end(strings), 
                              [&](std::string& s) { return s.find(pattern) == std::string::npos ; }) ; 

    strings.erase(pos, std::end(strings)) ;
}

void print(const std::vector<std::string>& strings)
{
    for ( auto& s : strings )
        std::cout << s << '\n' ;
}
@cire

Would it be better to use is_directory() rather than exists() on line 25 ?

Andy
andywestken wrote:
Would it be better to use is_directory() rather than exists() on line 25 ?

It could be, depending on the functionality you want. I would rather have an exception thrown if it's fed the name of a file, but I'm good with it just returning an empty list if the directory doesn't exist. Definitely something that should be noted in documentation, though.
Topic archived. No new replies allowed.