Como você obtém uma listview de diretórios em C?

Como você escaneia um diretório para pastas e arquivos em C? Precisa ser multi-plataforma.

O seguinte irá imprimir os nomes dos arquivos no diretório atual:

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

A resposta estrita é “você não pode”, como o próprio conceito de uma pasta não é verdadeiramente multi-plataforma.

Em plataformas MS, você pode usar _findfirst, _findnext e _findclose para um tipo de ‘c’, e FindFirstFile e FindNextFile para as chamadas subjacentes do Win32.

Aqui está a resposta do C-FAQ:

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

Eu criei um header C de código-fonte aberto (BSD) que lida com esse problema. Atualmente suporta POSIX e Windows. Por favor, confira:

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

Não há maneira padrão C (ou C ++) de enumerar arquivos em um diretório.

No Windows, você pode usar as funções FindFirstFile / FindNextFile para enumerar todas as inputs em um diretório. No Linux / OSX, use as funções opendir / readdir / closedir.

O GLib é uma biblioteca de portabilidade / utilitário para C, que forma a base do kit de ferramentas gráficas do GTK +. Pode ser usado como uma biblioteca independente.

Ele contém wrappers portáteis para gerenciar diretórios. Veja a documentação do Glib File Utilities para mais detalhes.

Pessoalmente, eu nem consideraria escrever grandes quantidades de código-C sem algo como o GLib atrás de mim. A portabilidade é uma coisa, mas também é bom obter estruturas de dados, ajudantes de encadeamento, events, mainloops etc. gratuitamente

Jikes, estou quase começando a soar como um cara de vendas 🙂 (não se preocupe, o glib é open source (LGPL) e eu não sou afiliado a ele de nenhuma forma)

opendir / readdir são POSIX. Se POSIX não for suficiente para a portabilidade que você deseja alcançar, verifique o Apache Portable Runtime

Listagem de diretório varia muito de acordo com o sistema operacional / plataforma em consideração. Isto porque, vários sistemas operacionais usando seu próprio sistema interno chama para conseguir isso.

Uma solução para este problema seria procurar uma biblioteca que mascara este problema e portátil. Infelizmente, não há solução que funcione em todas as plataformas sem falhas.

Em sistemas compatíveis com POSIX, você pode usar a biblioteca para obter isso usando o código postado por Clayton (que é referenciado originalmente pelo livro Advanced Programming in UNIX de W. Richard Stevens). essa solução funcionará em sistemas * NIX e também funcionará no Windows se você tiver o Cygwin instalado.

Como alternativa, você poderia escrever um código para detectar o SO subjacente e, em seguida, chamar a function de listview de diretórios apropriada que manteria a maneira ‘adequada’ de listar a estrutura de diretórios sob esse sistema operacional.

O método mais similar para readdir provavelmente está usando a família de funções _find pouco conhecida.

Você pode encontrar o código de exemplo no link wikibooks

 /************************************************************** * A simpler and shorter implementation of ls(1) * ls(1) is very similar to the DIR command on DOS and Windows. **************************************************************/ #include  #include  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; } 

Muito tarde, mas acho que não posso me segurar …

Usando o int system(char*) C int system(char*) você pode fazer todos os tipos de coisas através de uma interface C “portátil”. Você teria que carregar o aplicativo com o idioma específico do sistema (por exemplo, Shell / Bash, DOS, PowerShell), mas pelo menos você não precisará vincular bibliotecas extras. E, ao contrário do dirent , você pode fazer todo tipo de coisa “independente de plataforma” usando-o.

Exemplo de listview de diretórios com o linux (principalmente pseudo):

 system("ls . > some_file_or_pipe_or_whatever") // fscanf(file_or_pipe_or_whatever, "%s", a_line_from_ls);