2008-11-20 6 views

Antwort

2

Lösung dies wird eine plattformspezifische Lösung erfordern. Suchen Sie nach opendir() unter Unix/Linux oder FindFirstFile() unter Windows. Oder es gibt viele Bibliotheken, die den plattformspezifischen Teil für Sie übernehmen.

25

Hier ist ein Beispiel in C unter Linux. Das ist, wenn Sie auf Linux sind und nichts dagegen tun, diese kleine Spitze in ANSI C

#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); 
+10

vergessen Sie nicht, 'closedir (dpdf)' danach – jsj

+0

wie Kann ich in diesem Fall eine Datei (FILE type) bekommen? epdf ist ein "dirent *" –

+0

Dirent kann nicht verwendet werden, wenn Sie eine Lib erstellen. – Katianie

2

Wenn Sie in Windows & MSVC verwenden, hat die MSDN-Bibliothek sample code that does this.

Und hier ist der Code von diesem Link:

#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); 
} 
4

Sie müssen Betriebssystemaufrufe (z. B. die Win32 API) oder einen Wrapper um sie verwenden. Ich neige dazu, Boost.Filesystem zu verwenden, da es eine bessere Schnittstelle ist als das Chaos, das die Win32-API ist (und auch plattformübergreifend). Wenn Sie die Win32-API verwenden möchten, hat Microsoft eine Liste of functions und examples auf msdn.

56

Hier ist, was ich benutze:

/* 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 
+0

Der Windows-Code funktioniert nicht, wenn er mit Unicode kompiliert wird. Ich habe das umgangen, indem ich explizit die ASCII-Funktionen aufgerufen habe, denen ein 'A' angehängt ist. Verwenden Sie insbesondere WIN32_FIND_DATAA, FindFirstFileA und FindNextFileA und alles funktioniert. Offensichtlich ist das ein Hack, aber ich lebe in einem englischsprachigen Land, also funktioniert es für mich. : 0 Danke für den Beispielcode! – Joe

+5

Welche Header enthalten Sie, damit dies funktioniert? – emlai

+0

Dirent kann nicht verwendet werden, wenn Sie eine Lib erstellen. – Katianie

0
HANDLE WINAPI FindFirstFile(
    __in LPCTSTR lpFileName, 
    __out LPWIN32_FIND_DATA lpFindFileData 
); 

-Setup die Attribute nur für Verzeichnisse zu suchen.

0

Oder Sie tun dies, und dann die test.txt auslesen:

#include <windows.h> 

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

Die „/ b“ bedeutet nur Dateinamen zurückgegeben werden, keine weiteren Informationen.

+0

Das sieht wirklich nett und einfach aus, aber ich verstehe nicht, wie man das benutzt. Können Sie erklären, was '/ b' ist und wo werden wir das Verzeichnis angeben? – smttsp

-1
void getFilesList(String filePath,String extension, vector<string> & returnFileName) 
{ 
    WIN32_FIND_DATA fileInfo; 
    HANDLE hFind; 
    String fullPath = filePath + extension; 
    hFind = FindFirstFile(fullPath.c_str(), &fileInfo); 
    if (hFind == INVALID_HANDLE_VALUE){return;} 
    else { 
     return FileName.push_back(filePath+fileInfo.cFileName); 
     while (FindNextFile(hFind, &fileInfo) != 0){ 
      return FileName.push_back(filePath+fileInfo.cFileName);} 
     } 
} 


String optfileName ="";   
String inputFolderPath =""; 
String extension = "*.jpg*"; 
getFilesList(inputFolderPath,extension,filesPaths); 
vector<string>::const_iterator it = filesPaths.begin(); 
while(it != filesPaths.end()) 
{ 
    frame = imread(*it);//read file names 
      //doyourwork here (frame); 
    sprintf(buf, "%s/Out/%d.jpg", optfileName.c_str(),it->c_str()); 
    imwrite(buf,frame); 
    it++; 
} 
+0

Sie haben 2 Rückgabewerte in der Methode getFilesList, der Code nach dem return FileName.push_back (filePath + fileInfo.cFileName); ist nicht erreichbar – mmohab

0

Sie können den folgenden Code verwenden, um alle Dateien in einer directory.A einfachen Änderung in der Antwort Andreas Bonini für immer das Auftreten von entfernen „“ und ".."

2

Ich habe nur gefragt, eine ähnliche question und hier ist meine Lösung, die auf Antwort erhalten (mit boost::filesystem Bibliothek):

#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; 
    } 
} 

Ausgang ist wie:

file1.txt 
file2.dat 
+1

Ihre Antwort ist die beste ... – user1098761

1

Nachdem ich eine Menge Snippets kombiniert habe, habe ich endlich eine gefunden, die keine Fehler bringt, ein std :: string Argument akzeptiert und wiederverwendbar ist.

#include <atlstr.h> 

void getFiles(CString directory) { 
    Console console; 
    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 
     } 
    } 
} 

die Methode zuzugreifen, rufen Sie einfach:

getFiles("i:\\Folder1"); 
+0

Können Sie erwähnen, ob dies für Windows oder Linux oder beides ist? –

1

C++ 11/Linux-Version:

#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); 
} 
Verwandte Themen