2008-08-15 7 views

Respuesta

5

opendir/readdir son POSIX. Si POSIX no es suficiente para la portabilidad que quiere lograr, comprobar Apache Portable Runtime

68

Lo siguiente imprimirá los nombres de los archivos en el directorio actual:

#include <stdio.h> 
#include <sys/types.h> 
#include <dirent.h> 

int main (void) 
{ 
    DIR *dp; 
    struct dirent *ep;  
    dp = opendir ("./"); 

    if (dp != NULL) 
    { 
    while (ep = readdir (dp)) 
     puts (ep->d_name); 

    (void) closedir (dp); 
    } 
    else 
    perror ("Couldn't open the directory"); 

    return 0; 
} 

(crédito: http://www.gnu.org/software/libtool/manual/libc/Simple-Directory-Lister.html)

+1

Esto debería funcionar en Windows, así, al menos con MinGW. –

+1

@Clayton pero me han enseñado que nunca use puts() ya que no sabe cuántos caracteres imprimir? – YakRangi

+0

¿Qué tal esto '' error: nombre de tipo desconocido 'off64_t'' –

18

El la respuesta estricta es "no se puede", ya que el concepto mismo de una carpeta no es realmente multiplataforma.

En las plataformas MS puede usar _findfirst, _findnext y _findclose para una sensación de tipo 'c', y FindFirstFile y FindNextFile para las llamadas Win32 subyacentes.

Aquí está la C-respuesta FAQ:

http://c-faq.com/osdep/readdir.html

+0

¿Hay un alias ya configurado para _findfirst, _findnext y _findclose en algún lado? no en windows.h ¿verdad? – BuddyJoe

9

No hay manera estándar de C (o C++) para enumerar los archivos en un directorio.

en Windows, puede utilizar las funciones FindFirstFile/FindNextFile para enumerar todas las entradas en un directorio. En Linux/OSX, use las funciones opendir/readdir/closedir.

+0

Boost :: filesystem ?? – paxos1977

+1

@ceretullis: Tenga en cuenta la palabra "estándar" .. Boost aún no es estándar. – krebstar

+23

Boost tampoco es C. –

2

La lista de directorios varía mucho según el SO/plataforma en consideración. Esto se debe a que varios sistemas operativos usan sus propias llamadas internas del sistema para lograr esto.

Una solución a este problema sería la de buscar una biblioteca que enmascara este problema y portátiles. Lamentablemente, no existe una solución que funcione en todas las plataformas sin problemas.

En los sistemas compatibles con POSIX, puede utilizar la biblioteca para lograr esto utilizando el código publicado por Clayton (que se hace referencia originalmente de la Programación avanzada en el libro de UNIX de W. Richard Stevens). esta solución funcionará en sistemas * NIX y también funcionaría en Windows si tiene instalado Cygwin.

Alternativamente, se podría escribir un código para detectar el sistema operativo subyacente y luego llamar a la lista de directorios función apropiada que obstaculicen el camino 'adecuado' de la inclusión de la estructura de directorios en ese sistema operativo.

7

GLib es una biblioteca de portabilidad/utilidad para C que forma la base de la + conjunto de herramientas gráficas GTK. Se puede usar como una biblioteca independiente.

Contiene envoltorios portátiles para la gestión de directorios. Consulte la documentación de Glib File Utilities para obtener detalles.

En lo personal, yo ni siquiera que no hacer grandes cantidades de C-código sin algo así como GLib detrás de mí. La portabilidad es una cosa, pero también es bueno obtener estructuras de datos, ayudantes de subprocesos, eventos, mainloops, etc. gratis

Jikes, estoy empezando a sonar como un vendedor :) (no te preocupes, glib es de código abierto (LGPL) y yo no estoy afiliado con él de alguna manera)

+2

+1; La función relevante es 'g_dir_read_name()' – weiqure

13

He creado un encabezado C de código abierto (BSD) que se ocupa de este problema. Actualmente es compatible con POSIX y Windows. Por favor, echa un vistazo:

https://github.com/cxong/tinydir

tinydir_dir dir; 
tinydir_open(&dir, "/path/to/dir"); 

while (dir.has_next) 
{ 
    tinydir_file file; 
    tinydir_readfile(&dir, &file); 

    printf("%s", file.name); 
    if (file.is_dir) 
    { 
     printf("/"); 
    } 
    printf("\n"); 

    tinydir_next(&dir); 
} 

tinydir_close(&dir); 
+0

¿Cómo ayuda esto más que las implementaciones originales dependientes del sistema? ¿O es para que solo necesite una biblioteca nombrada para Windows y POSIX? – kevr

+0

'votar' por tinydir.h, bien hecho. –

-1

Puede encontrar el código de ejemplo en la wikibooks link

/************************************************************** 
* A simpler and shorter implementation of ls(1) 
* ls(1) is very similar to the DIR command on DOS and Windows. 
**************************************************************/ 
#include <stdio.h> 
#include <dirent.h> 

int listdir(const char *path) 
{ 
    struct dirent *entry; 
    DIR *dp; 

    dp = opendir(path); 
    if (dp == NULL) 
    { 
    perror("opendir"); 
    return -1; 
    } 

    while((entry = readdir(dp))) 
    puts(entry->d_name); 

    closedir(dp); 
    return 0; 
} 

int main(int argc, char **argv) { 
    int counter = 1; 

    if (argc == 1) 
    listdir("."); 

    while (++counter <= argc) { 
    printf("\nListing %s...\n", argv[counter-1]); 
    listdir(argv[counter-1]); 
    } 

    return 0; 
} 
Cuestiones relacionadas