Como listar arquivos em um diretório em um programa C?

88

Estou tentando escrever um servidor ftp no Linux. Neste assunto, como posso listar arquivos no diretório no terminal por um programa C? Talvez eu possa usar a função exec para executar o comando find, mas quero o nome do arquivo como uma string para enviar o programa cliente. Como posso fazer isso?

Obrigado pelas respostas.

cemal
fonte

Respostas:

175

Um exemplo, disponível para sistemas compatíveis com POSIX:

/*
 * This program displays the names of all files in the current directory.
 */

#include <dirent.h> 
#include <stdio.h> 

int main(void) {
  DIR *d;
  struct dirent *dir;
  d = opendir(".");
  if (d) {
    while ((dir = readdir(d)) != NULL) {
      printf("%s\n", dir->d_name);
    }
    closedir(d);
  }
  return(0);
}

Esteja ciente de que tal operação depende da plataforma em C.

Fonte: http://faq.cprogramming.com/cgi-bin/smartfaq.cgi?answer=1046380353&id=1044780608

Jean-Bernard Jansen
fonte
está tudo bem agora e tão fácil. Obrigado pela resposta novamente.
cemal
13
valide se gostou;)
Jean-Bernard Jansen
1
Ótimo, mas e se quisermos apenas pngarquivos?
Farsheed de
2
@Farsheed: tente isso .
Fraxtil,
Eu encontro poucos problemas com isso. Primeiro, "." e ".." aparecem no topo de cada diretório e, embora sejam "diretórios", eles têm o dir-> d_type definido como DT_REG. Além disso, não consigo obter todos os arquivos ... Existe um código de "scanner de diretório" mais abrangente em algum lugar? Talvez a implementação de "ls" por algum pobre-homem? Eu preciso disso no Mac - OS-X
Motti Shneor
35

Uma pequena adição à resposta de JB Jansen - no readdir()loop principal, eu adicionaria isto:

  if (dir->d_type == DT_REG)
  {
     printf("%s\n", dir->d_name);
  }

Apenas verificando se é realmente um arquivo, e não um link (sym), diretório ou qualquer outra coisa.

NOTA: mais sobre struct direntna libcdocumentação .

Kamiccolo
fonte
6
Apenas uma observação: nem todas as plataformas serão preenchidas d_type, mas o Linux e o BSD irão (eu sei que a pergunta está marcada como Linux, apenas estendendo um pouco a resposta); mesmo assim, nem todos os sistemas de arquivos são suportados uniformemente , no entanto, deve funcionar com a maioria dos FSs.
omninonsense
11

Aqui está um programa completo para listar recursivamente o conteúdo da pasta:

#include <dirent.h> 
#include <stdio.h> 
#include <string.h>

#define NORMAL_COLOR  "\x1B[0m"
#define GREEN  "\x1B[32m"
#define BLUE  "\x1B[34m"



/* let us make a recursive function to print the content of a given folder */

void show_dir_content(char * path)
{
  DIR * d = opendir(path); // open the path
  if(d==NULL) return; // if was not able return
  struct dirent * dir; // for the directory entries
  while ((dir = readdir(d)) != NULL) // if we were able to read somehting from the directory
    {
      if(dir-> d_type != DT_DIR) // if the type is not directory just print it with blue
        printf("%s%s\n",BLUE, dir->d_name);
      else
      if(dir -> d_type == DT_DIR && strcmp(dir->d_name,".")!=0 && strcmp(dir->d_name,"..")!=0 ) // if it is a directory
      {
        printf("%s%s\n",GREEN, dir->d_name); // print its name in green
        char d_path[255]; // here I am using sprintf which is safer than strcat
        sprintf(d_path, "%s/%s", path, dir->d_name);
        show_dir_content(d_path); // recall with the new path
      }
    }
    closedir(d); // finally close the directory
}

int main(int argc, char **argv)
{

  printf("%s\n", NORMAL_COLOR);

    show_dir_content(argv[1]);

  printf("%s\n", NORMAL_COLOR);
  return(0);
}
Faroq AL-Tam
fonte
4

O código abaixo só imprimirá arquivos dentro do diretório e excluirá os diretórios dentro de um determinado diretório durante o percurso.

#include <dirent.h>
#include <stdio.h>
#include <errno.h>
#include <sys/stat.h>
#include<string.h>
int main(void)
{
    DIR *d;
    struct dirent *dir;
    char path[1000]="/home/joy/Downloads";
    d = opendir(path);
    char full_path[1000];
    if (d)
    {
        while ((dir = readdir(d)) != NULL)
        {
            //Condition to check regular file.
            if(dir->d_type==DT_REG){
                full_path[0]='\0';
                strcat(full_path,path);
                strcat(full_path,"/");
                strcat(full_path,dir->d_name);
                printf("%s\n",full_path);
            }
        }
        closedir(d);
    }
    return(0);     
}
Alegria
fonte