47

ディレクトリ内のファイルのリストを取得して、それぞれを処理できるようにするにはどうすればよいですか?

4

13 に答える 13

61

これが私が使用するものです:

/* Returns a list of files in a directory (except the ones that begin with a dot) */

void GetFilesInDirectory(std::vector<string> &out, const string &directory)
{
#ifdef WINDOWS
    HANDLE dir;
    WIN32_FIND_DATA file_data;

    if ((dir = FindFirstFile((directory + "/*").c_str(), &file_data)) == INVALID_HANDLE_VALUE)
        return; /* No files found */

    do {
        const string file_name = file_data.cFileName;
        const string full_file_name = directory + "/" + file_name;
        const bool is_directory = (file_data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) != 0;

        if (file_name[0] == '.')
            continue;

        if (is_directory)
            continue;

        out.push_back(full_file_name);
    } while (FindNextFile(dir, &file_data));

    FindClose(dir);
#else
    DIR *dir;
    class dirent *ent;
    class stat st;

    dir = opendir(directory);
    while ((ent = readdir(dir)) != NULL) {
        const string file_name = ent->d_name;
        const string full_file_name = directory + "/" + file_name;

        if (file_name[0] == '.')
            continue;

        if (stat(full_file_name.c_str(), &st) == -1)
            continue;

        const bool is_directory = (st.st_mode & S_IFDIR) != 0;

        if (is_directory)
            continue;

        out.push_back(full_file_name);
    }
    closedir(dir);
#endif
} // GetFilesInDirectory
于 2009-12-19T12:58:24.897 に答える
35

しかし、boost::filesystemそれを行うことができます: http://www.boost.org/doc/libs/1_37_0/libs/filesystem/example/simple_ls.cpp

于 2008-11-20T19:24:45.383 に答える
28

Linux上のCの例を次に示します。その場合は、Linuxを使用していて、ANSICでこの小さなことを行ってもかまいません。

#include <dirent.h>

DIR *dpdf;
struct dirent *epdf;

dpdf = opendir("./");
if (dpdf != NULL){
   while (epdf = readdir(dpdf)){
      printf("Filename: %s",epdf->d_name);
      // std::cout << epdf->d_name << std::endl;
   }
}
closedir(dpdf);
于 2008-11-20T21:30:36.550 に答える
6

C++11/Linux バージョン:

#include <dirent.h>

if (auto dir = opendir("some_dir/")) {
    while (auto f = readdir(dir)) {
        if (!f->d_name || f->d_name[0] == '.')
            continue; // Skip everything that starts with a dot

        printf("File: %s\n", f->d_name);
    }
    closedir(dir);
}
于 2017-09-07T22:00:23.947 に答える
4

オペレーティングシステムコール(Win32 APIなど)またはそれらのラッパーを使用する必要があります。私はBoost.Filesystemを使用する傾向があります。これは、Win32 API(およびクロスプラットフォーム)である混乱と比較して優れたインターフェイスであるためです。

Win32 APIの使用を検討している場合、Microsoftにはmsdnの関数例のリストがあります。

于 2009-12-19T12:56:05.037 に答える
3

同様の質問をしましたが、これが受け取った回答に基づく私の解決策です(boost::filesystemライブラリを使用):

#include <string>
#include <iostream>
#include <boost/filesystem.hpp>
using namespace std;
using namespace boost::filesystem;

int main()
{
    path p("D:/AnyFolder");
    for (auto i = directory_iterator(p); i != directory_iterator(); i++)
    {
        if (!is_directory(i->path())) //we eliminate directories in a list
        {
            cout << i->path().filename().string() << endl;
        }
        else
            continue;
    }
}

出力は次のようになります。

file1.txt
file2.dat
于 2015-06-25T16:26:43.213 に答える
3

Windows で MSVC を使用している場合、MSDN ライブラリにはこれを行うサンプル コードがあります。

そして、そのリンクからのコードは次のとおりです。

#include <windows.h>
#include <tchar.h> 
#include <stdio.h>
#include <strsafe.h>

void ErrorHandler(LPTSTR lpszFunction);

int _tmain(int argc, TCHAR *argv[])
{
   WIN32_FIND_DATA ffd;
   LARGE_INTEGER filesize;
   TCHAR szDir[MAX_PATH];
   size_t length_of_arg;
   HANDLE hFind = INVALID_HANDLE_VALUE;
   DWORD dwError=0;

   // If the directory is not specified as a command-line argument,
   // print usage.

   if(argc != 2)
   {
      _tprintf(TEXT("\nUsage: %s <directory name>\n"), argv[0]);
      return (-1);
   }

   // Check that the input path plus 2 is not longer than MAX_PATH.

   StringCchLength(argv[1], MAX_PATH, &length_of_arg);

   if (length_of_arg > (MAX_PATH - 2))
   {
      _tprintf(TEXT("\nDirectory path is too long.\n"));
      return (-1);
   }

   _tprintf(TEXT("\nTarget directory is %s\n\n"), argv[1]);

   // Prepare string for use with FindFile functions.  First, copy the
   // string to a buffer, then append '\*' to the directory name.

   StringCchCopy(szDir, MAX_PATH, argv[1]);
   StringCchCat(szDir, MAX_PATH, TEXT("\\*"));

   // Find the first file in the directory.

   hFind = FindFirstFile(szDir, &ffd);

   if (INVALID_HANDLE_VALUE == hFind) 
   {
      ErrorHandler(TEXT("FindFirstFile"));
      return dwError;
   } 

   // List all the files in the directory with some info about them.

   do
   {
      if (ffd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
      {
         _tprintf(TEXT("  %s   <DIR>\n"), ffd.cFileName);
      }
      else
      {
         filesize.LowPart = ffd.nFileSizeLow;
         filesize.HighPart = ffd.nFileSizeHigh;
         _tprintf(TEXT("  %s   %ld bytes\n"), ffd.cFileName, filesize.QuadPart);
      }
   }
   while (FindNextFile(hFind, &ffd) != 0);

   dwError = GetLastError();
   if (dwError != ERROR_NO_MORE_FILES) 
   {
      ErrorHandler(TEXT("FindFirstFile"));
   }

   FindClose(hFind);
   return dwError;
}


void ErrorHandler(LPTSTR lpszFunction) 
{ 
    // Retrieve the system error message for the last-error code

    LPVOID lpMsgBuf;
    LPVOID lpDisplayBuf;
    DWORD dw = GetLastError(); 

    FormatMessage(
        FORMAT_MESSAGE_ALLOCATE_BUFFER | 
        FORMAT_MESSAGE_FROM_SYSTEM |
        FORMAT_MESSAGE_IGNORE_INSERTS,
        NULL,
        dw,
        MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
        (LPTSTR) &lpMsgBuf,
        0, NULL );

    // Display the error message and exit the process

    lpDisplayBuf = (LPVOID)LocalAlloc(LMEM_ZEROINIT, 
        (lstrlen((LPCTSTR)lpMsgBuf)+lstrlen((LPCTSTR)lpszFunction)+40)*sizeof(TCHAR)); 
    StringCchPrintf((LPTSTR)lpDisplayBuf, 
        LocalSize(lpDisplayBuf) / sizeof(TCHAR),
        TEXT("%s failed with error %d: %s"), 
        lpszFunction, dw, lpMsgBuf); 
    MessageBox(NULL, (LPCTSTR)lpDisplayBuf, TEXT("Error"), MB_OK); 

    LocalFree(lpMsgBuf);
    LocalFree(lpDisplayBuf);
}
于 2008-11-20T22:19:40.693 に答える
2

これを解決するには、プラットフォーム固有のソリューションが必要です。unix/linux では opendir() を、Windows では FindFirstFile() を探してください。または、プラットフォーム固有の部分を処理する多くのライブラリがあります。

于 2008-11-20T19:25:43.040 に答える
1

多くのスニペットを組み合わせた後、Visual Studio に付属している ATL ライブラリを使用する Windows 用の再利用可能なソリューションを最終的に見つけました。

#include <atlstr.h>

void getFiles(CString directory) {
    HANDLE dir;
    WIN32_FIND_DATA file_data;
    CString  file_name, full_file_name;
    if ((dir = FindFirstFile((directory + "/*"), &file_data)) == INVALID_HANDLE_VALUE)
    {
        // Invalid directory
    }

    while (FindNextFile(dir, &file_data)) {
        file_name = file_data.cFileName;
        full_file_name = directory + file_name;
        if (strcmp(file_data.cFileName, ".") != 0 && strcmp(file_data.cFileName, "..") != 0)
        {
            std::string fileName = full_file_name.GetString();
            // Do stuff with fileName
        }
    }
}

メソッドにアクセスするには、次のように呼び出します。

getFiles("i:\\Folder1");
于 2016-06-19T14:53:20.583 に答える
0
HANDLE WINAPI FindFirstFile(
  __in   LPCTSTR lpFileName,
  __out  LPWIN32_FIND_DATA lpFindFileData
);

ディレクトリのみを検索するように属性を設定します。

于 2009-12-19T12:59:13.533 に答える
0

次のコードを使用して、ディレクトリ内のすべてのファイルを取得できます。Andreas Bonini の回答を簡単に変更して、「。」の出現を削除します。と ".."

CString dirpath="d:\\mydir"
DWORD errVal = ERROR_SUCCESS;
HANDLE dir;
WIN32_FIND_DATA file_data;
CString  file_name,full_file_name;
if ((dir = FindFirstFile((dirname+ "/*"), &file_data)) == INVALID_HANDLE_VALUE)
{
    errVal=ERROR_INVALID_ACCEL_HANDLE;
    return errVal;
}

while (FindNextFile(dir, &file_data)) {
    file_name = file_data.cFileName;
    full_file_name = dirname+ file_name;
    if (strcmp(file_data.cFileName, ".") != 0 && strcmp(file_data.cFileName, "..") != 0)
    {
        m_List.AddTail(full_file_name);
    }
}
于 2014-07-03T09:50:18.510 に答える
0

または、これを実行してから、test.txt を読み取ります。

#include <windows.h>

int main() {    
system("dir /b > test.txt");
}

「/b」は、ファイル名のみが返され、それ以上の情報が返されないことを意味します。

于 2013-07-02T23:41:07.850 に答える