¿Cómo obtengo una lista de archivos en un directorio en C ++?

¿Cómo se obtiene una lista de archivos dentro de un directorio para que cada uno pueda ser procesado?

El estándar C ++ no proporciona una forma de hacer esto. Pero boost::filesystem puede hacer eso: http://www.boost.org/doc/libs/1_37_0/libs/filesystem/example/simple_ls.cpp

Esto es lo que uso:

 /* Returns a list of files in a directory (except the ones that begin with a dot) */ void GetFilesInDirectory(std::vector &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 

Aquí hay un ejemplo en C en Linux. Eso es si, estás en Linux y no te importa hacer esto pequeño en ANSI C.

 #include  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); 

Debe usar llamadas al sistema operativo (por ejemplo, la API de Win32) o un envoltorio alrededor de ellas. Tiendo a utilizar Boost.Filesystem ya que es una interfaz superior en comparación con el desastre que es la API de Win32 (además de ser multiplataforma).

Si está buscando utilizar la API de Win32, Microsoft tiene una lista de funciones y ejemplos en msdn.

Para resolver esto, se necesitará una solución específica para la plataforma. Busque opendir () en Unix / Linux o FindFirstFile () en Windows. O bien, hay muchas bibliotecas que manejarán la parte específica de la plataforma para usted.

Si está en Windows y usa MSVC, la biblioteca de MSDN tiene un código de muestra que hace esto.

Y aquí está el código de ese enlace:

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

Acabo de hacer una pregunta similar y esta es mi solución basada en la respuesta recibida (usando la biblioteca boost::filesystem ):

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

La salida es como:

 file1.txt file2.dat 

Versión C ++ 11 / Linux:

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

Después de combinar muchos fragmentos, finalmente encontré una solución reutilizable para Windows que usa ATL Library, que viene con Visual Studio.

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

Para acceder al método, simplemente llame:

 getFiles("i:\\Folder1"); 

O haz esto y luego lee el test.txt:

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

El “/ b” significa que solo se devuelven los nombres de los archivos, no hay más información.

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

Configure los atributos solo para buscar directorios.

Puede usar el siguiente código para obtener todos los archivos en un directorio. Una simple modificación en la respuesta de Andreas Bonini para eliminar la ocurrencia de “.” y “..”

 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); } } 
 void getFilesList(String filePath,String extension, vector & 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::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++; }