c ++文件夹只搜索

时间:2017-10-05 15:01:03

标签: c++ winapi directory

我需要获取目录中的文件夹列表,但只能获取文件夹。不需要任何文件。只有文件夹。我使用过滤器来确定这是否是一个文件夹,但它们不起作用,并且输出所有文件和文件夹。

find(...)
    S.find(sub [,start [,end]]) -> int

    Return the lowest index in S where substring sub is found,
    such that sub is contained within S[start:end].  Optional
    arguments start and end are interpreted as in slice notation.

    Return -1 on failure.

通过这种方式,我检查它是否是一个文件夹。

string root = "D:\\*";
cout << "Scan " << root << endl;
std::wstring widestr = std::wstring(root.begin(), root.end());
const wchar_t* widecstr = widestr.c_str();
WIN32_FIND_DATAW wfd;
HANDLE const hFind = FindFirstFileW(widecstr, &wfd);

如何解决问题?

2 个答案:

答案 0 :(得分:2)

此函数将文件夹收集到给定的向量中。如果将 recursive 设置为true,它将扫描文件夹内的文件夹等文件夹。

// TODO: proper error handling.

void GetFolders( std::vector<std::wstring>& result, const wchar_t* path, bool recursive )
{
    HANDLE hFind;
    WIN32_FIND_DATA data;
    std::wstring folder( path );
    folder += L"\\";
    std::wstring mask( folder );
    mask += L"*.*";

    hFind=FindFirstFile(mask.c_str(),&data);
    if(hFind!=INVALID_HANDLE_VALUE)
    {
        do
        {
            std::wstring    name( folder );
            name += data.cFileName;
            if ( ( data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY )
                 // I see you don't want FILE_ATTRIBUTE_REPARSE_POINT
                 && !( data.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT ) )
            {
                // Skip . and .. pseudo folders.
                if ( wcscmp( data.cFileName, L"." ) != 0 && wcscmp( data.cFileName, L".." ) != 0 )
                {
                    result.push_back( name );
                    if ( recursive )
                        // TODO: It would be wise to check for cycles!
                        GetFolders( result, name.c_str(), recursive );
                }
            }
        } while(FindNextFile(hFind,&data));
    }
    FindClose(hFind);
}

https://stackoverflow.com/a/46511952/8666197修改

答案 1 :(得分:2)

有两种方法可以做到这一点:艰难的方式和简单的方法。

困难的方法基于FindFirstFileFindNextFile,根据需要过滤掉目录。您将在Stack Overflow以及互联网的其他部分找到一系列概述这种方法的样本。

简单方法:使用标准directory_iterator类(或recursive_directory_iterator,如果需要递归到子目录中)。解决方案就像 1

一样简单
<input type="text" name="form_submitted" value="1"/> 

<html> 

<head>

<title>Registration Form</title> 

<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> 

</head> 

<body> 

<?php if (isset($_POST['form_submitted'])): ?> 

<?php if (!isset($_POST['agree'])): ?> 

<p>You have not accepted our terms of service</p> 

<?php else: ?> 

<h2>Thank You <?php echo $_POST['firstname']; ?></h2> 

<p>You have been registered as <?php echo $_POST['firstname'] . ' ' . $_POST['lastname']; ?>  </p>

<p> Go <a href="sample.php" >back</a> to the form</p> 

<?php endif; ?> 

<?php else: ?> 

<h2>Registration Form</h2> 

<form action="sample.php" method="POST">

First name: <input type="text" name="firstname"><br>

Last name: <input type="text" name="lastname"><br> 

Agree to Terms of Service: <input type="checkbox" name="agree"> <br> 

**<input type="hidden" name="form_submitted" value="1"/>** 

<input type="submit" value="Submit"> 

</form> 

<?php endif; ?> 

</body> 

</html>

您必须包含C ++ 17中引入的<filesystem>头文件。

注意:使用最新版本的Visual Studio 2017(15.3.5),这还不在for ( const auto& entry : directory_iterator( path( L"abc" ) ) ) { if ( is_directory( entry.path() ) ) { // Do something with the entry visit( entry.path() ); } } 中。您必须改为引用namespace std

<小时/> 1 特别注意,不需要过滤掉namespace std::experimental::filesystem.伪目录;那些不是由目录迭代器返回的。