Searching for files in a directory by name using Visual Studio C++

徘徊边缘 提交于 2021-01-28 11:09:23

问题


I'm trying to create a program where I can search for some files in a directory on my PC, using Visual Studio C++. As I'm not very experienced with that, I found this code (below) in another answer but couldn't find any explanation to the code. I'm having a hard time figuring it out and would strongly appreciate any help possible.

If there's another way of doing this I would be pleased to know how. Thank you!

" Now you can get file names. Just compare a file name.

 while ((dirp = readdir(dp)) != NULL) {
       std::string fname = dirp->d_name;
       if(fname.find("abc") != std::string::npos)
          files.push_back(fname);
    }

Also you can use scandir function which can register filter function.

 static int filter(const struct dirent* dir_ent)
    {
        if (!strcmp(dir_ent->d_name, ".") || !strcmp(dir_ent->d_name, "..")) 
    return 0;
        std::string fname = dir_ent->d_name;

        if (fname.find("abc") == std::string::npos) return 0;

        return 1;
    }


    int main()
    {
        struct dirent **namelist;

        std::vector<std::string> v;
        std::vector<std::string>::iterator  it;

        n = scandir( dir_path , &namelist, *filter, alphasort );

        for (int i=0; i<n; i++) {
            std::string fname = namelist[i]->d_name;

            v.push_back(fname);

            free(namelist[i]);
        }
        free(namelist);

    return 0;
    }

"


回答1:


A better way of doing this would probably be using the new std::filesystem library. directory_iterators allow you to go through the contents of a directory. Since they are just iterators, you can combine them with standard algorithms like std::find_if to search for a particular entry:

#include <filesystem>
#include <algorithm>

namespace fs = std::filesystem;

void search(const fs::path& directory, const fs::path& file_name)
{
    auto d = fs::directory_iterator(directory);

    auto found = std::find_if(d, end(d), [&file_name](const auto& dir_entry)
    {
        return dir_entry.path().filename() == file_name;
    });

    if (found != end(d))
    {
        // we have found what we were looking for
    }

    // ...
}

We first create a directory_iterator d for the directory in which we want to search. We then use std::find_if() to go through the contents of the directory and search for an entry that matches the filename we are looking for. std::find_if() expects a function object as last argument that is applied to every visited element and returns true if the element matches what we are looking for. std::find_if() returns the iterator to the first element for which this predicate function returns true, otherwise it returns the end iterator. Here, we use a lambda as predicate that returns true when the filename component of the path of the directory entry we're looking at matches the wanted filename. Afterwards, we compare the iterator returned by std::find_if() to the end iterator to see if we have found an entry or not. In case we did find an entry, *found will evaluate to a directory_entry representing the respective file system object.

Note that this will require a recent version of Visual Studio 2017. Don't forget to set the language standard to /std:c++17 or /std:c++latest in the project properties (C++/Language).




回答2:


Both methods use the find function of a std::string:

   fname.find("abc")

This looks for "abc" in the fname string. If it's found it returns the index it starts at, otherwise it retruns std::string::npos, so they both check for that substring.

You may want to see if you have an exact match, using == instead. It depends.

If an appropriate filename is found, it's pushed back into a vector. Your main function has

std::vector<std::string>::iterator  it;

which it doesn't use. I suspect that came over with some copy/paste.

You can use a range based for loop to see what's in your vector:

for(const std::string & name : v)
{
    std::cout << name << '\n';
}

The filter function also checks against "." and ".." since these have special meanings - current dir and up one dir. At that point, th C API has returned a char *, so they use strcmp, rather than std::string methods.


Edit:

n = scandir( dir_path , &namelist, *filter, alphasort );

uses n which you haven't declared. Try

int n = scandir( dir_path , &namelist, *filter, alphasort );

Also, that uses dir_path which needs declaring somewhere.

For a quick fix, try

const char * dir_path = "C:\\";

(or whatever path you want, watching out for escaping backslashes with an extra backslash.

You probably want to pass this in as an arg to main.



来源:https://stackoverflow.com/questions/51378530/searching-for-files-in-a-directory-by-name-using-visual-studio-c

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!