Come posso ottenere un elenco di file in una directory in C ++?

Come si ottiene un elenco di file all’interno di una directory in modo che ciascuno possa essere elaborato?

Il C ++ standard non fornisce un modo per farlo. Ma boost::filesystem può farlo: http://www.boost.org/doc/libs/1_37_0/libs/filesystem/example/simple_ls.cpp

Ecco cosa 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 

Ecco un esempio in C su Linux. Questo è se, sei su Linux e non ti importa fare questo piccolo bit in 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); 

Devi utilizzare le chiamate del sistema operativo (ad esempio l’API Win32) o un wrapper attorno ad esse. Tendo ad usare Boost.Filesystem in quanto è un’interfaccia superiore rispetto al pasticcio che è l’API Win32 (oltre ad essere multipiattaforma).

Se stai cercando di utilizzare l’API Win32, Microsoft ha un elenco di funzioni ed esempi su msdn.

Risolvere questo richiederà una soluzione specifica per la piattaforma. Cerca opendir () su unix / linux o FindFirstFile () su Windows. Oppure, ci sono molte librerie che gestiranno la parte specifica della piattaforma per te.

Se ti trovi in ​​Windows e utilizzi MSVC, la libreria MSDN dispone di codice di esempio che esegue questa operazione.

Ed ecco il codice da quel link:

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

Ho appena fatto una domanda simile ed ecco la mia soluzione basata sulla risposta ricevuta (usando boost::filesystem libreria 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; } } 

L'output è come:

 file1.txt file2.dat 

Versione 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); } 

Dopo aver combinato molti frammenti, ho finalmente trovato una soluzione riutilizzabile per Windows, che utilizza la libreria ATL, fornita 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 } } } 

Per accedere al metodo, basta chiamare:

 getFiles("i:\\Folder1"); 

O fai questo e poi leggi il test.txt:

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

“/ B” significa che vengono restituiti solo i nomi dei file, senza ulteriori informazioni.

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

Imposta gli attributi per cercare solo le directory.

È ansible utilizzare il seguente codice per ottenere tutti i file in una directory. Una semplice modifica nella risposta di Andreas Bonini per rimuovere l’occorrenza di “.” e “..”

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