2008-11-20 11 views

Répondre

2

La résolution de ce problème nécessitera une solution spécifique à la plate-forme. Recherchez opendir() sur unix/linux ou FindFirstFile() sous Windows. Ou, il y a beaucoup de bibliothèques qui s'occuperont de la partie spécifique à la plate-forme pour vous.

25

Voici un exemple dans C sous Linux. C'est si vous êtes sous Linux et ne rechignent pas à faire ce petit peu dans la norme 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

n'oubliez pas de 'closedir (DPDF)' après – jsj

+0

comment puis-je obtenir un fichier (type fichier) dans ce cas? epdf est un "dirent *" –

+0

Impossible d'utiliser dirent si vous faites une lib. – Katianie

2

Si vous êtes sous Windows & en utilisant MSVC, la bibliothèque MSDN a sample code that does this.

Et voici la code à partir de ce lien:

#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

Vous devez utiliser les appels du système d'exploitation (par exemple l'API Win32) ou un wrapper autour d'eux. J'ai tendance à utiliser Boost.Filesystem car c'est une interface supérieure par rapport au désordre qui est l'API Win32 (en plus d'être multi-plateforme). Si vous cherchez à utiliser l'API Win32, Microsoft a une liste of functions et examples sur msdn.

56

Voici ce que j'utilise:

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

Le code Windows ne fonctionne pas correctement lorsqu'il est compilé avec Unicode activé. J'ai contourné ceci en appelant explicitement les fonctions ASCII, qui ont un 'A' ajouté. Plus précisément, utilisez WIN32_FIND_DATAA, FindFirstFileA et FindNextFileA et tout fonctionne. Évidemment, c'est un hack, mais je vis dans un pays anglophone donc ça marche pour moi. : 0 Merci pour le code d'exemple! – Joe

+5

Quels en-têtes incluez-vous pour que cela fonctionne? – emlai

+0

Impossible d'utiliser dirent si vous créez une bibliothèque. – Katianie

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

Configuration des attributs à ne rechercher des répertoires.

0

Ou vous faites cela et lire le test.txt:

#include <windows.h> 

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

Le "/ b" signifie simplement noms sont retournés, pas d'info plus loin.

+0

Cela semble vraiment agréable et facile, mais je ne comprends pas comment l'utiliser. Pourriez-vous expliquer ce qu'est '/ b' et où allons-nous donner le répertoire? – 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

vous avez 2 retours dans la méthode getFilesList, le code après le retour FileName.push_back (filePath + fileInfo.cFileName); n'est pas accessible – mmohab

0

Vous pouvez utiliser le code suivant pour obtenir tous les fichiers dans une simple modification directory.A dans la réponse Andreas Bonini pour enlever le occurance de « » et ".."

2

Je viens juste de demander un semblable question et voici ma solution basée sur la réponse reçue (en utilisant la bibliothèque 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; 
    } 
} 

est sortie comme:

file1.txt 
file2.dat 
+1

Votre réponse est la meilleure ... – user1098761

1

Après avoir combiné beaucoup de snippets, j'en ai finalement trouvé un qui n'apporte pas d'erreurs, acceptera un argument std :: string et est réutilisable.

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

Pour accéder à la méthode, il suffit d'appeler:

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

Pouvez-vous indiquer si c'est pour Windows ou Linux ou les deux? –

1

C++ 11/version 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); 
} 
Questions connexes