【问题标题】:Windows fnmatch substituteWindows fnmatch 替代品
【发布时间】:2016-03-08 20:49:51
【问题描述】:

我在 Linux 中有以下代码来查找与给定通配符匹配的文件:

    std::vector<std::string> listFilenamesInPath(std::string wildcard = "*", std::string directory = "./")
    {
        std::vector<std::string> result;
        DIR* dirp = opendir(directory.c_str());

        if (dirp)
        {
            while (true)
            {
                struct dirent* de = readdir(dirp);

                if (de == NULL)
                    break;

                if (fnmatch(wildcard.c_str(), de->d_name, 0))
                    continue;
                else
                    result.push_back (std::string(de->d_name));
            }

            closedir(dirp);
        }

        std::sort(result.begin(), result.end());

        return result;
    }

我正在将此代码移植到Windows,发现fnmatch不可用(dirent也不可用,但我可以根据以下SO link找到一个。

是否有一个 fnmatch 替代函数可以做完全相同的事情?

如何在不破坏逻辑的情况下让这段代码在 VS2012 中编译和运行?

【问题讨论】:

  • msdn.microsoft.com/en-us/library/windows/desktop/… FindFirstFile(),FindNextFile()... 函数系列可能就是您要找的。​​span>
  • 如果 boost 是一个选项,它会提供在 Linux 和 Windows 上运行的类似功能。 boost::filesystem , boost::path 等

标签: c++ windows visual-studio-2010


【解决方案1】:

感谢 SergeyA 的帮助。这是我的最终解决方案,以防将来有人需要......

#ifdef _WIN32
#include "dirent.h"
#include "windows.h"
#include "shlwapi.h"
#else
#include <dirent.h>
#include <fnmatch.h>
#endif
    std::vector<std::string> listFilenamesInPath(std::string wildcard = "*", std::string directory = "./")
    {
        std::vector<std::string> result;

        DIR* dirp = opendir(directory.c_str());

        if (dirp)
        {
            while (true)
            {
                struct dirent* de = readdir(dirp);

                if (de == NULL)
                    break;

#ifdef _WIN32
            wchar_t wname[1024];
            wchar_t wmask[1024];

            size_t outsize;
            mbstowcs_s(&outsize, wname, de->d_name, strlen(de->d_name) + 1);
            mbstowcs_s(&outsize, wmask, wildcard.c_str(), strlen(wildcard.c_str()) + 1);

            if (PathMatchSpecW(wname, wmask))
                result.push_back (std::string(de->d_name));
            else
                continue;
#else
                if (fnmatch(wildcard.c_str(), de->d_name, 0))
                    continue;
                else
                    result.push_back (std::string(de->d_name));
#endif
            }

            closedir(dirp);
        }

        std::sort(result.begin(), result.end());

        return result;
    }

如果有什么可以改进的请评论...

【讨论】:

    【解决方案2】:

    看起来 PathMatchSpec 是你的人。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2010-09-06
      • 2010-11-28
      • 1970-01-01
      • 2010-12-24
      • 2015-09-13
      • 1970-01-01
      • 2010-12-03
      相关资源
      最近更新 更多