2008-11-20 11 views

Respuesta

2

Resolver esto requerirá una solución específica de 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.

25

Aquí hay un ejemplo en C en Linux. Eso si, estás en Linux y no le importa hacer este pequeño fragmento en 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

no se olvide de 'closedir (DPDF)' después – jsj

+0

cómo ¿Puedo obtener un archivo (tipo de archivo) en este caso? epdf es un "dirent *" –

+0

No se puede usar dirent si está creando una lib. – Katianie

2

Si estás en Windows & usando MSVC, la biblioteca MSDN tiene sample code that does this.

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

#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

Tienes que usar las llamadas al sistema operativo (por ejemplo, la API Win32) o un contenedor alrededor de ellas. Tiendo a usar 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 Win32, Microsoft tiene una lista of functions y examples en msdn.

56

Esto es lo que yo uso:

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

El código de Windows no funciona cuando se compila con Unicode habilitado. Lo solucioné llamando explícitamente a las funciones ASCII, que tienen una 'A' adjuntada. Específicamente, use WIN32_FIND_DATAA, FindFirstFileA y FindNextFileA y todo funciona. Obviamente, este es un truco, pero yo vivo en un país de habla inglesa, así que funciona para mí. : 0 Gracias por el código de ejemplo! – Joe

+5

¿Qué encabezados incluye para que esto funcione? – emlai

+0

No se puede usar dirent si está creando una lib. – Katianie

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

Configuración de los atributos para que busque sólo para los directorios.

0

O haces esto y luego leer el test.txt:

#include <windows.h> 

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

El "/ B" significa que sólo se devuelven los nombres de archivo, sin más información.

+0

Esto se ve muy bien y fácil, pero no entiendo cómo usar esto. ¿Podría explicar qué es '/ b' y dónde le daremos el directorio? – 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

tiene 2 devoluciones en el método getFilesList, el código después de la devolución FileName.push_back (filePath + fileInfo.cFileName); no es alcanzable – mmohab

0

Usted puede utilizar el siguiente código para conseguir todos los archivos en una simple modificación en la respuesta directory.A Andreas Bonini para eliminar la ocurrencia de "" y ".."

2

he acaba de pedir un question similares y aquí está mi solución basada en la respuesta recibida (usando boost::filesystem biblioteca):

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

de salida es como:

file1.txt 
file2.dat 
+1

Su respuesta es la mejor ... – user1098761

1

Después de combinar muchos fragmentos, finalmente encontré uno que no trae errores, aceptará un argumento std :: string y es reutilizable.

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

Para acceder al método, a llamarlo:

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

¿Puede mencionar si esto es para Windows o Linux o ambos? –

1

C++ 11/Linux versión:

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